我使用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 中编写它的等价物。
答案 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配置更易于维护。