我有一个类似于:
的StructureMap配置cfg.For<ICacheOrder>().Use<CacheOrder>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ICacheProduct>().Use<CacheProduct>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ISQLOrder>().Use<SQLOrder>().Ctor<int>().Is(context => LoginHelper.LoginID);
cfg.For<ISQLProduct>().Use<SQLProduct>().Ctor<int>().Is(context => LoginHelper.LoginID);
通过构造函数注入,可以创建一个对象链,其中一些对象需要一个在创建时确定的int LoginID。静态LoginHelper确定LoginID。
目前在我的配置中,为每个创建的对象调用LoginHelper。有没有办法,也许是通过StructureMap的IContext,让LoginID成为&#34;记住&#34;并且只在创作链中确定一次?
我知道我可以重构并创建一个可以构造和缓存的ILogin接口/具体 - 但我更喜欢我的各个层只关注一个简单的int LoginID。
答案 0 :(得分:3)
虽然可以在服务中注入原始配置值,但是当您将相同的原语重复注入多个服务时,您将缺少抽象。
您的配置显然就是这种情况;你错过了抽象。
解决方案是让这些服务依赖于抽象而不是原始值。例如:
public interface ICurrentUser
{
int LoginID { get; }
}
您可以创建一个相当简单的实现,如下所示:
public class CurrentUserImpl : ICurrentUser
{
public CurrentUserImpl()
{
this.LoginID = LoginHelper.LoginID;
}
public int LoginID { get; private set; }
}
这意味着您必须更改CacheOrder
,CacheProduct
,SQLOrder
和SQLProduct
的构造函数,但是当您执行此操作时,您的配置可以更加可维护:
cfg.For<ICacheOrder>().Use<CacheOrder>();
cfg.For<ICacheProduct>().Use<CacheProduct>();
cfg.For<ISQLOrder>().Use<SQLOrder>();
cfg.For<ISQLProduct>().Use<SQLProduct>();
“记住param文字”的问题现在立即消失,因为我们现在可以注册ICurrentUser
如下:
cfg.For<ICurrentUser>().Use<CurrentUserImpl>();
结构图中的默认生命周期是每个请求(每个对象图),因此同一个实例将被注入单个对象图中的所有对象。
另一种选择是使用HttpContext
生命周期注册它,但这当然只适用于运行ASP.NET Web应用程序。