2013-08-02 107 views
19

在Castle Windsor註冊組件時,我們如何將接口的特定實現綁定到對該接口有依賴性的組件。我事先知道組件需要使用哪些實現。Castle Windsor - 接口的多個實現

例如,我基於幾個博客和教程的代碼創建了一個示例控制檯應用程序。

以下是驗證碼。

public interface IReport 
{ 
    void LogReport(); 
} 

public interface ILogger 
{ 
    string Log(); 
} 

public class FileLogger : ILogger 
{ 
    public string Log() 
    { 
     return "Logged data to a file"; 
    } 
} 

public class DatabaseLogger : ILogger 
{ 
    public string Log() 
    { 
     return "Logged data to a database"; 
    } 
} 

public class McAfeeService : IReport 
{ 
    private readonly ILogger _logger; 

    public McAfeeService(ILogger logger) 
    { 
     this._logger = logger; 
    } 

    public void LogReport() 
    { 
     string getLogResult = this._logger.Log(); 

     Console.WriteLine("McAfee Scan has " + getLogResult); 
    }   
} 

public class NortonService : IReport 
{ 
    private readonly ILogger _logger; 

    public NortonService(ILogger logger) 
    { 
     this._logger = logger; 
    } 

    public void LogReport() 
    { 
     string getLogResult = this._logger.Log(); 

     Console.WriteLine("Norton Scan has " + getLogResult); 
    } 
} 

class Program 
{ 
    private static IWindsorContainer container; 

    static void Main(string[] args) 
    { 
     // Register components 
     container = new WindsorContainer(); 

     container.Register(Component.For<IReport>().ImplementedBy<NortonService>()); 
     container.Register(Component.For<ILogger>().ImplementedBy<FileLogger>()); 

     IReport service = container.Resolve<IReport>(); 
     service.LogReport(); 

     Console.ReadLine(); 
    } 
} 

我希望NortonService始終使用Filelogger和McAfeeService來使用數據庫記錄器。

在上述程序中,我無法將NortonService綁定到FileLogger。

怎麼辦?

回答

2

我的答案也許不是最好的,你可以使用命名方法來解決多執行:

container.Register(Component.For(typeof(ILogger)) 
      .ImplementedBy(typeof(FileLogger)) 
      .Named("FileLoggerIoC") 
      .LifestylePerWebRequest() , 
      Component.For(typeof(ILogger)) 
      .ImplementedBy(typeof(DatabaseLogger)) 
      .Named("DatabaseLoggerIoC") 
      .LifestylePerWebRequest()); 

在您的通話功能,則需要通過名字來解決這個問題: -

var fileLog = container.Resolve("FileLoggerIoC", typeof(ILogger)); 
var DbLog = container.Resolve("DatabaseLoggerIoC", typeof(ILogger)); 

礦山方法可能不是最好的方法,因爲人們不喜歡服務定位器來獲取組件,您可以將其用作臨時解決方案。

20

以上的答案使我內聯依賴和功能service override

下面是註冊碼:

container.Register(Component.For<IReport>().ImplementedBy<NortonService>().Named("nortonService")); 

container.Register(Component.For<ILogger>().ImplementedBy<FileLogger>()); 
container.Register(Component.For<ILogger>().ImplementedBy<DatabaseLogger>()); 

container.Register(
    Component.For<IReport>().ImplementedBy<McAfeeService>().Named("mcafeeService") 
     .DependsOn(Dependency.OnComponent<ILogger, DatabaseLogger>()) 
); 

IReport mcafeescan = container.Resolve<IReport>("mcafeeService"); 
mcafeescan.LogReport(); 

IReport nortonscan = container.Resolve<IReport>("nortonService"); 
nortonscan.LogReport(); 

輸出:

McAfee Scan has Logged data to a database 
Norton Scan has Logged data to a file 
9

我有一個問題非常喜歡這一點,兩個實現一個接口和兩個實現另一個接口。我想強制使用這些接口的特定實現。

我的階級結構看起來像這樣 -

enter image description here

我看着的命名慣例,但真的不喜歡它。相反,我用下面的 - 對這種做法

public void Install(IWindsorContainer container, IConfigurationStore store) 
    { 
    container.Register(
     Component.For<IMessageLoader>().ImplementedBy<MessageLoaderDatabase>() 
     ,Component.For<IMessageLoader>().ImplementedBy<MessageLoaderFile>() 

     ,Component.For<IMessageOfTheDayService>().ImplementedBy<MessageOfTheDayServiceDatabase>() 
      .DependsOn(Dependency.OnComponent<IMessageLoader, MessageLoaderDatabase>()) 

     ,Component.For<IMessageOfTheDayService>().ImplementedBy<MessageOfTheDayServiceFile>() 
      .DependsOn(Dependency.OnComponent<IMessageLoader, MessageLoaderFile>()) 

     ,Component.For<MessageOfTheDayController>().LifestyleTransient() 
      .DependsOn(Dependency.OnComponent<IMessageOfTheDayService, MessageOfTheDayServiceFile>()) 
    ); 

全部信息是here。在該帖子提供的源代碼中,我展示了獲得相同結果的另外兩種方法。

2

如果你想在運行時做到這一點,這可以通過IHandlerSelector來完成。編寫一個實現IHandlerSelector的類。它提供了一個方法SelectHandler,它可以讓你在運行時有條件地定義綁定條件。在這種情況下,處理程序是Windsor中的一個參與實例構建的組件。有關更多詳細信息,請參閱here

相關問題