2013-07-23 26 views
2

我試圖註冊幾個與Windsor容器共享相同接口ISetting的類型。Windsor基於通用接口的組件註冊

說明性ISetting接口不需要任何實現。它的唯一目的是幫助定位組件中的設置類型。否則,這些設置類型不會以任何方式,形狀或形式相互關聯。

通常我會創建這些類型的一個接一個與沿着這些線路代碼:

var settingsManager = new SettingsManager(); 
var applicationSettings = settingsManager.LoadSettings<ApplicationSettings>(); 
var emailSettings = settingsManager.LoadSettings<EmailSettings>(); 

但我想按照慣例註冊這些組件,所以我沒有做手工。

到目前爲止,我已經在WindsorInstallers之一下面的代碼:

container.Register(Classes.FromAssemblyContaining<ISetting>() 
            .BasedOn<ISetting>() 
            ...help... 
            ); 

澄清:設置會以班級爲具體類型內使用(見下文)

public class Service2 
{ 
    private readonly EmailSettings _settings; 

    public Service2(EmailSettings settings) 
    { 
     _settings = settings; 
    } 

    public void Awesome() 
    { 
     Console.WriteLine(_settings.Value); 
    } 
} 

我的目標:儘管我可以逐個將所有設置類型注入容器,但我正在尋找一種解決方案,可以找到並註冊從繼承的所有類型使用一個(也許兩個)語句。

回答

5

這取決於你想如何使用它(注吧)

這裏是一個可能的解決方案

container.Register(
Classes 
    .FromThisAssembly() 
    .BasedOn<ISettings>() 
    .WithServiceSelf() //for way 3 
    .WithServiceFirstInterface() //way 1 & 2 
    .Configure(c => c.Named(c.Implementation.Name)) //way 1 & 2 
    ); 

方法1 - 直接解決 - 您將使用這個我不認爲一個

在你的例子中你直接獲取設置,你可以使用帶有容器的命名參數如下

var settings = container.Resolve<ISettings>("EmailSettings");

當以這種方式解析設置時,我們使用named參數來選擇正確的實現。

路2 - 注射用命名的參數

在這種情況下,我們有一個服務如下(再次猜測可能的使用率)

public class Service1 
{ 
    private readonly ISettings _emailSettings; 

    public Service1(ISettings emailSettings) 
    { 
     _emailSettings = emailSettings; 
    } 

    public void Awesome() 
    { 
     Console.WriteLine(_emailSettings.Value); 
    } 
} 

這個工作,我們需要註冊鍵入以使用具有構造函數參數的指定參數,如下所示:

//using a named parameter 
container.Register(
    Component.For<Service1>().ImplementedBy<Service1>() 
    .DependsOn(Dependency.OnComponent(typeof(ISettings), "EmailSettings"))); 

取決於尋找屬性/ ctor params來注入。然後它使用指定的實現。

方式3 - 我們使用的直下式

這種可能的方式假定服務知道它需要一個具體類型,例如:

public class Service2 
{ 
    private readonly EmailSettings _settings; 

    public Service2(EmailSettings settings) 
    { 
     _settings = settings; 
    } 

    public void Awesome() 
    { 
     Console.WriteLine(_settings.Value); 
    } 
} 

這一個註冊相同通常

//using the actual type 
container.Register(Component.For<Service2>().ImplementedBy<Service2>()); 

關鍵部分是如何註冊您的設置類型。如果我沒有覆蓋您的使用,請提供一些更多信息。

希望這可以幫助

+0

謝謝你的迴應。我在原始問題中做了一些澄清,以更好地描述需要什麼。 – Valera

+0

方式3 :)應該工作,使用頂部的註冊。那麼任何需要具體類型的組件都會被注入。請注意,設置僅被註冊一次。 – dbones

+0

方式3將註冊所有具體的「ISetting」實現 - 這是真的。但我需要通過'settingsManager.LoadSettings ()其中T:ISetting'來運行每個類。這聽起來像我應該利用UsingFactoryMethod來配置每個組件,但我無法提供確切的語法。 – Valera

相關問題