在SO上回答this question时,我无法找到在SimpleInjector中注册LifetimeScopeLifestyle
实例的泛型类型的许多实现的最佳技术。
此注册形式的推荐方法如下:
container.RegisterManyForOpenGeneric(typeof(IRepository<>),
typeof(IRepository<>).Assembly);
但是这不允许传入LifetimeScopeLifestyle
的实例。
以下是我提出的内容,但我知道它不够灵活,因为它正在检查任何通用接口,而不是IRepository<>
。谁能告诉我怎么做?
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);
}
}
答案 0 :(得分:3)
<强> TLDR:强>
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
lifetimeScope,
typeof(IRepository<>).Assembly);
首先,您的查询是错误的。应该是:
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 };
其次,框架包含一个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 };
但是它变得更好,容器包含RegisterManyForOpenGeneric
方法的重载,该方法接受一个回调委托,允许您按如下方式进行注册:
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
(service, impls) =>
{
container.Register(service, impls.Single(),
lifetimeScope);
},
typeof(IRepository<>).Assembly);
但最重要的是,该框架包含RegisterManyForOpenGeneric
重载,其中包含Lifetime
。因此,您可以将注册简化为以下内容:
container.RegisterManyForOpenGeneric(
typeof(IRepository<>),
lifetimeScope,
typeof(IRepository<>).Assembly);