简体   繁体   English

Castle Windsor:开放泛型类型的条件注册

[英]Castle Windsor: Conditional registration of open generic types

I have the following: 我有以下内容:

class Repository<T> : IRepository<T>
interface ISuperRepository<T> : IRepository<T>
class SuperRepository<T> : ISuperRepository<T>
interface ISuperType

I want conditional registration in Castle Windsor DI for IRepository<T> , if T is ISuperType , then provide ISuperRepository<T> . 我想在Castle Windsor DI中IRepository<T>进行条件注册,如果TISuperType ,则提供ISuperRepository<T> Else, provide IRepository<T>. 否则,提供IRepository<T>.

So for example, if A : ISuperType , then I want Resolve<IRepository<A>> to provide SuperRepository<A> , and Resolve<IRepository<B>> to provide Repository<B> . 例如,如果A : ISuperType ,那么我希望Resolve<IRepository<A>>提供SuperRepository<A> ,并且Resolve<IRepository<B>>提供Repository<B>

How can I achive that? 我怎么能做到这一点?

Castle Windsor doesn't support such a thing, however you can achieve it with a simple helper method: 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>>());
}

Then the registration: 然后注册:

container.RegisterAccordingToISuperType<SuperType>();
container.RegisterAccordingToISuperType<int>();

And the resolve will: 并且决心将:

var super = container.Resolve<IRepository<SuperType>>();
var intRepo = container.Resolve<IRepository<int>>();

Another option is to the extra parameter in Component.For . 另一个选项是Component.For的额外参数。 Then gets all type which inherite form the Type( For example ) and register them. 然后获取从Type( 例如 )继承的所有类型并注册它们。

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;
}

You can restrict what types a generic is used for with the "where T: typename" syntax, where "typename" refers to a type the specified type 'T' must inherit (or implement). 您可以使用“where T:typename”语法限制泛型的类型,其中“typename”指的是指定类型“T”必须继承(或实现)的类型。 In your case "where T: ISuperType" would match the specific types, and a version without the restriction should match all the rest. 在您的情况下,“其中T:ISuperType”将匹配特定类型,没有限制的版本应匹配所有其余类型。

ref. REF。 https://msdn.microsoft.com/en-us/library/bb384067.aspx https://msdn.microsoft.com/en-us/library/bb384067.aspx

If it can't be done at compile-time, it can always be done at runtime (with f.ex. 'is'). 如果它不能在编译时完成,它总是可以在运行时完成(使用f.ex。'是')。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM