Castle Windsor:开放泛型类型的条件注册
Castle Windsor: Conditional registration of open generic types
我有以下内容:
class Repository<T> : IRepository<T>
interface ISuperRepository<T> : IRepository<T>
class SuperRepository<T> : ISuperRepository<T>
interface ISuperType
我想在 Castle Windsor DI 中有条件地注册 IRepository<T>
,如果 T
是 ISuperType
,则提供 ISuperRepository<T>
.否则,提供 IRepository<T>.
所以比如A : ISuperType
,那么我要Resolve<IRepository<A>>
提供SuperRepository<A>
,Resolve<IRepository<B>>
提供Repository<B>
。
我怎样才能做到这一点?
您可以使用 "where T: typename" 语法限制泛型用于哪些类型,其中 "typename" 指的是指定类型 'T' 必须继承(或实现)的类型。在您的情况下 "where T: ISuperType" 将匹配特定类型,没有限制的版本应该匹配所有其他类型。
参考。 https://msdn.microsoft.com/en-us/library/bb384067.aspx
如果无法在编译时完成,则始终可以在运行时完成(使用 f.ex。'is')。
Castle Windsor
不支持这样的事情,但是你可以用一个简单的辅助方法来实现它:
public static void RegisterAccordingToISuperType<T>(this IWindsorContainer container)
{
if (typeof (T).GetInterfaces().Contains(typeof (ISuperType)))
container.Register(Component.For<IRepository<T>>()
.ImplementedBy<SuperRepository<T>>());
else
container.Register(Component.For<IRepository<T>>()
.ImplementedBy<Repository<T>>());
}
然后报名:
container.RegisterAccordingToISuperType<SuperType>();
container.RegisterAccordingToISuperType<int>();
决心将:
var super = container.Resolve<IRepository<SuperType>>();
var intRepo = container.Resolve<IRepository<int>>();
另一个选项是 Component.For
中的额外参数。然后获取继承自 Type(For example) 的所有类型并注册它们。
private static void Register(...)
{
foreach (var type in GetInheriteTypes())
{
container.Register(Component.For(typeof(IRepository<>),type)
.ImplementedBy(typeof(SuperRepository<>)));
}
container.Register(Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>)));
}
private static IEnumerable<Type> GetInheriteTypes()
{
var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
from assemblyType in domainAssembly.GetTypes()
where assemblyType.GetInterfaces().Contains(typeof(ISuperType))
select assemblyType).ToArray();
return listOfBs;
}
我有以下内容:
class Repository<T> : IRepository<T>
interface ISuperRepository<T> : IRepository<T>
class SuperRepository<T> : ISuperRepository<T>
interface ISuperType
我想在 Castle Windsor DI 中有条件地注册 IRepository<T>
,如果 T
是 ISuperType
,则提供 ISuperRepository<T>
.否则,提供 IRepository<T>.
所以比如A : ISuperType
,那么我要Resolve<IRepository<A>>
提供SuperRepository<A>
,Resolve<IRepository<B>>
提供Repository<B>
。
我怎样才能做到这一点?
您可以使用 "where T: typename" 语法限制泛型用于哪些类型,其中 "typename" 指的是指定类型 'T' 必须继承(或实现)的类型。在您的情况下 "where T: ISuperType" 将匹配特定类型,没有限制的版本应该匹配所有其他类型。
参考。 https://msdn.microsoft.com/en-us/library/bb384067.aspx
如果无法在编译时完成,则始终可以在运行时完成(使用 f.ex。'is')。
Castle Windsor
不支持这样的事情,但是你可以用一个简单的辅助方法来实现它:
public static void RegisterAccordingToISuperType<T>(this IWindsorContainer container)
{
if (typeof (T).GetInterfaces().Contains(typeof (ISuperType)))
container.Register(Component.For<IRepository<T>>()
.ImplementedBy<SuperRepository<T>>());
else
container.Register(Component.For<IRepository<T>>()
.ImplementedBy<Repository<T>>());
}
然后报名:
container.RegisterAccordingToISuperType<SuperType>();
container.RegisterAccordingToISuperType<int>();
决心将:
var super = container.Resolve<IRepository<SuperType>>();
var intRepo = container.Resolve<IRepository<int>>();
另一个选项是 Component.For
中的额外参数。然后获取继承自 Type(For example) 的所有类型并注册它们。
private static void Register(...)
{
foreach (var type in GetInheriteTypes())
{
container.Register(Component.For(typeof(IRepository<>),type)
.ImplementedBy(typeof(SuperRepository<>)));
}
container.Register(Component.For(typeof(IRepository<>))
.ImplementedBy(typeof(Repository<>)));
}
private static IEnumerable<Type> GetInheriteTypes()
{
var listOfBs = (from domainAssembly in AppDomain.CurrentDomain.GetAssemblies()
from assemblyType in domainAssembly.GetTypes()
where assemblyType.GetInterfaces().Contains(typeof(ISuperType))
select assemblyType).ToArray();
return listOfBs;
}