在SimpleInjector how中使用构造函数注册泛型类型
本文关键字:构造函数 注册 泛型类型 SimpleInjector how | 更新日期: 2023-09-27 18:26:15
我使用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中编写它的等价物。
您的配置没有什么特别之处,@Patryk在这里为您指出了正确的文档。SimpleInjector将为您进行自动连接,因此您不必显式指定构造函数参数。
但是,您当前的设置有一些臭味,因为您的DbContext
似乎是一个单例;在整个应用程序期间,您只有一个实例。在几乎所有情况下,这都是一个非常糟糕的主意。应用程序的使用寿命很长(例如Windows服务),或者同时处理多个线程(例如ASP.NET和WCF)。只有在您有一个生存时间很短的单线程应用程序(例如控制台应用程序)的情况下,您可能只有一个DbContext。您不希望将DbContext注册为singleton。
但也许它不是一个singleton,并且您实际上在每个请求中调用这个RegisterTypes
一次。在这种情况下,每个请求将有一个DbContext,但这意味着每个请求都要创建一个新的容器实例,这也会很糟糕。这将对Unity和Simple Injector的性能非常不利。DI库经过特别优化,在应用程序的持续时间内只有一个容器实例。
因此,您更希望在应用程序期间有一个单独的容器实例,并让您的DbContext通常使用Scoped生活方式注册。
在Simple Injector中,有许多范围内的生活方式,每种生活方式都特定于所选的技术。假设您使用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配置更易于维护。