2015-07-19 75 views
3

我有以下几点:温莎城堡:开放式泛型类型的有条件注册

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

我想有条件注册在温莎城堡DIIRepository<T>,如果TISuperType,然后提供ISuperRepository<T>。否则,提供IRepository<T>.

因此,举例来说,如果A : ISuperType,那么我想Resolve<IRepository<A>>提供SuperRepository<A>,并Resolve<IRepository<B>>提供Repository<B>

我该如何存档?

+0

每一层间接(又名有条件)都是由另一层抽象 - FactoryProvider解决的。 –

回答

2

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>>(); 

另一个选项是中的额外参数210。然后获取所有类型(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; 
} 
+0

感谢您的回应 - 我有很多类实现ISuperType,所以我喜欢第二种方法,但它似乎并不工作 - 解决类型总是SuperRepository 而不是存储库。 – Rita

+0

@Rita你的'Resolve'看起来如何?如果'Resolve'看起来像我的例子,它应该是工作(它在我的电脑里工作) –

+0

@Rita还有一件事,确认你没有在foreach之前注册一些东西,如果你这样做了,你必须使用'默认()'扩展方法。 –

-1

您可以使用“where T:typename”语法限制泛型的使用类型,其中“typename”指的是指定类型'T'必须继承(或实现)的类型。在你的情况下,“T:ISuperType”将与特定类型匹配,没有限制的版本应该与其余所有匹配。

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

如果它不能在编译时完成,它总是可以在运行时完成(f.ex.'is')。

+1

这不是我遇到的问题。我正在寻找一种方式在Castle Windsor DI进行有条件注册。 – Rita

+0

提供“注册”意味着“正在运行的代码”(虽然我对该主题有一个粗略的理解,但我从未深入研究过),如果T是类型ISuperType,将会阻止测试的结果是什么?我在这里假设这些存储库对象有一个小的“工厂”,所以它可以选择正确的一个。 – tamlin

+2

@tamlin您可能想了解[一般DI是什么](https://en.wikipedia.org/wiki/Dependency_injection)以及[Castle Windsor](https://github.com/castleproject/Windsor/blob) /master/docs/README.md)是特别的。 – GSerg