每个Web请求和上下文的简单注入器寄存器

Vla*_*irs 6 c# dependency-injection simple-injector

RegisterPerWebRequestRegisterWithContext(这一个最初并没有附带简单的喷射器,但是它在高级方案部分提供).另外两种方法都可以正常工作,但我需要将它们结合起来.

我发现在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

Ste*_*ven 8

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整个图中重用的记录器.但是没有人会期望ILoggerHomeController构造函数中删除它会导致记录器LoggingCommandHandlerDecorator<ShipOrder>发生变化.

这就是扩展方法中没有Lifestyle参数的原因RegisterWithContext.