Vla*_*irs 6 c# dependency-injection simple-injector
有RegisterPerWebRequest和RegisterWithContext(这一个最初并没有附带简单的喷射器,但是它在高级方案部分提供).另外两种方法都可以正常工作,但我需要将它们结合起来.
我发现在RegisterPerWebRequest使用过的new WebRequestLifestyle()生活方式中(在那里发现).所以不是使用Lifestyle.Transient RegisterWithContext我提供的,new WebRequestLifestyle()而是看起来DependencyContext.ImplementationType并且DependencyContext.ServiceType为空.
这有什么问题?
更新1.
因此,我希望像每个Web请求一样注册类型,RegisterPerWebRequest但也能够为实例创建者提供对注入注册类型的类型的访问权限.
我修改(提取生活方式作为参数)RegisterWithContext为:
public static void RegisterWithContext<TService>(
this Container container,
Func<DependencyContext, TService> contextBasedFactory, Lifestyle lifestyle)
where TService : class
{
//original code
container.Register<TService>(rootFactory, lifestyle);
//original code
}
Run Code Online (Sandbox Code Playgroud)
对于"每个Web请求和上下文"注册,我希望能够使用:
container.RegisterWithContext<IUnitOfWork>(dependencyContext =>
{
var implementationType = dependencyContext.ImplementationType;
//do some stuff and return preconfigured UnitOfWork
}, new WebRequestLifestyle());
Run Code Online (Sandbox Code Playgroud)
正如我已经提到dependencyContext.ImplementationType的那样NULL
我正在使用SimpleInjector 2.3.0.0
该RegisterWithContext扩展方法明确地注册提供委托作为Transient.这样做是因为将该类型注册到任何其他生活方式都没有意义.
生活方式的概念WebRequestLifestyle是在整个对象图中缓存和重用相同的实例(可能超出该范围).这个概念然而,基于上下文的注册打交道时,仅仅是因为基于上下文的情况下,预计每次被注射时间是不同的意义不大.换句话说,为每个消费者提供一个唯一的实例与重用相同实例的概念相冲突.
举个例子来看看下面的对象图:
new HomeController(
new Logger("HomeController"),
new LoggingRepositoryDecorator<User>(
new Logger("LoggingRepositoryDecorator<User>"),
new SqlRepository<User>(
new DbContext())),
new LoggingCommandHandlerDecorator<ShipOrder>(
new Logger("LoggingCommandHandlerDecorator<ShipOrder>"),
new ShipOrderCommandHandler(
new DbContext())));
Run Code Online (Sandbox Code Playgroud)
在这个对象图中,我们创建了一个HomeController带有依赖关系.该Logger组件显然是一个基于上下文的组件,因为它每次都基于其父级进行不同的初始化.这将是注册Logger:
container.RegisterWithContext<ILogger>(context =>
new Logger(context.ImplementationType.Name));
Run Code Online (Sandbox Code Playgroud)
但是,如果我们允许ILogger注册注册,则WebRequestLifestyle每次都应该应用相同的实例,这可能会导致以下对象图:
ILogger logger = new Logger(typeName: "HomeController");
new HomeController(
logger,
new LoggingRepositoryDecorator<User>(
logger,
new SqlRepository<User>(
new DbContext())),
new LoggingCommandHandlerDecorator<ShipOrder>(
logger,
new ShipOrderCommandHandler(
new DbContext())));
Run Code Online (Sandbox Code Playgroud)
在这个对象图Logger("HomeController")中注入了相同的内容,这显然不是我们想要的.此外,行为变得非常不可预测,因为首先创建的是消费者,这将决定在typeName整个图中重用的记录器.但是没有人会期望ILogger从HomeController构造函数中删除它会导致记录器LoggingCommandHandlerDecorator<ShipOrder>发生变化.
这就是扩展方法中没有Lifestyle参数的原因RegisterWithContext.
| 归档时间: |
|
| 查看次数: |
3151 次 |
| 最近记录: |