如何用LifetimeScopeLifestyle注册一个泛型类型的多个实现
本文关键字:泛型类型 一个 实现 LifetimeScopeLifestyle 注册 何用 | 更新日期: 2023-09-27 18:10:04
在SO上回答这个问题时,我无法找出在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);
}
}
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);