2015-07-19 79 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