[英]SimpleInjector - how to register many implementations of a generic type with LifetimeScopeLifestyle?
While answering this question on SO I couldn't figure out the best technique for registering many implementations of a generic type with an instance of LifetimeScopeLifestyle
within SimpleInjector. 在SO上回答这个问题时 ,我无法找到在SimpleInjector中使用LifetimeScopeLifestyle
实例注册许多泛型类型实现的最佳技术。
The recommended method for this form of registration is something like this: 这种注册形式的推荐方法是这样的:
container.RegisterManyForOpenGeneric(typeof(IRepository<>),
typeof(IRepository<>).Assembly);
But this does not allow an instance of LifetimeScopeLifestyle
to be passed in. 但是这不允许传入LifetimeScopeLifestyle
的实例。
Below is what I came up with but I know it's not resilient enough as it is checking for any generic interface, not specifically IRepository<>
. 下面是我提出的,但我知道它不够有弹性,因为它正在检查任何通用接口,而不是特定的IRepository<>
。 Can anyone tell me how to do this? 谁能告诉我怎么做?
public static void Configure(Container container)
{
var lifetimeScope = new LifetimeScopeLifestyle();
container.Register<IUnitOfWork, UnitOfWork>(lifetimeScope);
//this query needs improvement
var registrations =
from type in typeof(IRepository<>).Assembly.GetExportedTypes()
where typeof(IRepository).IsAssignableFrom(type)
&& type.IsClass
&& !type.IsAbstract
from service in type.GetInterfaces()
where service.IsGenericType
select new { Service = service, Implementation = type };
foreach (var registration in registrations)
{
container.Register(registration.Service,
registration.Implementation, lifetimeScope);
}
}
TLDR: TLDR:
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
lifetimeScope,
typeof(IRepository<>).Assembly);
First of all, your query is wrong. 首先,您的查询是错误的。 It should have been: 应该是:
var registrations =
from type in
typeof(IRepository<>).Assembly.GetExportedTypes()
where !service.IsAbstract
where !service.IsGenericTypeDefinition
from @interface in type.GetInterfaces()
where @interface.IsGenericType
where @interface.GetGenericTypeDefinition() ==
typeof(IRepository<>)
select new { Service = @interface, Impl = type };
Second, the framework contains a GetTypesToRegister
method to fetch these types for you, which excludes decorator types: 其次,框架包含一个GetTypesToRegister
方法来为您提取这些类型,这会排除装饰器类型:
var repositoryTypes =
OpenGenericBatchRegistrationExtensions.GetTypesToRegister(
container, typeof(IRepository<>),
typeof(IRepository<>).Assembly);
var registrations =
from type in repositoryTypes
from @interface in type.GetInterfaces()
where @interface.IsGenericType
where @interface.GetGenericTypeDefinition() ==
typeof(IRepository<>)
select new { Service = @interface, Impl = type };
But it gets better, the container contains an overload of the RegisterManyForOpenGeneric
method that takes a callback delegate that allows you to do the registration as follows: 但它变得更好,容器包含RegisterManyForOpenGeneric
方法的重载,该方法采用允许您按如下方式进行注册的回调委托:
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
(service, impls) =>
{
container.Register(service, impls.Single(),
lifetimeScope);
},
typeof(IRepository<>).Assembly);
But most importantly, the framework contains RegisterManyForOpenGeneric
overloads that takes in an Lifetime
. 但最重要的是,该框架包含接收Lifetime
RegisterManyForOpenGeneric
重载。 So you are able to simplify your registration to the following: 因此,您可以将注册简化为以下内容:
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
lifetimeScope,
typeof(IRepository<>).Assembly);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.