在SimpleInjector中使用构造函数注册泛型类型如何?

时间:2014-10-12 18:35:05

标签: c# dependency-injection inversion-of-control unity-container simple-injector

我使用Microsoft Unity作为IoC容器并编写了一些代码:

public static void RegisterTypes(IUnityContainer container)
{
    MyContext ctx = new MyContext (); // is EntityFramework DbContext
    container.RegisterType(typeof(IEntityRepository<>),
                           typeof(EntityRepository<>), 
                           new InjectionConstructor(ctx));
    container.RegisterType(typeof(IEntityService<>), 
                           typeof(EntityService<>));
}

它对我没有问题,但我想知道如何在 SimpleInjector 中编写它的等价物。

1 个答案:

答案 0 :(得分:3)

您的配置没有什么特别之处,@ Patryk指出了正确的文档here。 Simple Injector将为您进行自动连线,因此您不必明确指定构造函数参数。

但是你的当前设置有点臭,因为好像你的DbContext是单身人士;在整个申请期间,您只有一个实例。几乎在所有情况下都是very bad idea。您的应用程序可以存在很长时间(例如Windows服务)或同时处理多个线程(例如ASP.NET和WCF)。只有在您拥有一个非常短时间的单线程应用程序(例如控制台应用程序)的情况下,您可能只有一个DbContext。您不希望将DbContext注册为单身。

但也许它不是单身人士,你实际上每次请求都会调用RegisterTypes一次。在这种情况下,每个请求将有一个DbContext,但这意味着您为每个请求创建一个新的容器实例,这也是不好的。对Unity和Simple Injector的性能来说,这将是非常糟糕的。 DI库特别针对在应用程序期间拥有一个容器实例进行了优化。

因此,您希望在应用程序的持续时间内拥有一个单独的容器实例,并让您的DbContext通常以Scoped生活方式注册。

在Simple Injector中有many scoped lifestyles,每一个都针对所选技术。假设您使用的是MVC,您的注册可能如下所示:

public static void RegisterTypes(Container container)
{
    container.Options.DefaultScopedLifestyle = new WebRequestLifestyle();

    container.Register<MyContex>(Lifestyle.Scoped);

    container.Register(typeof(IEntityRepository<>), typeof(EntityRepository<>));

    container.Register(typeof(IEntityService<>), typeof(EntityService<>));
}

请注意EntityRepository<T>的注册。如果EntityRepository<T>的构造函数参数为MyContext,并且MyContext已在容器中注册,则Simple Injector将能够在其构造函数中为您注入此依赖项。这个过程称为自动布线,您通常应该让容器为您执行此操作,因为这样可以使您的DI配置更易于维护。