Dependency injection 基于配置解决依赖关系

Dependency injection 基于配置解决依赖关系,dependency-injection,castle-windsor,ioc-container,Dependency Injection,Castle Windsor,Ioc Container,在我的windows服务应用程序中,我需要在服务启动时使用配置解析组件。我使用温莎城堡作为我的IoC容器 应用程序看起来像: public class RootComponent : IRootComponent { public RootComponent (IDataProvider1 provider1, IDataProvider2 provider2) { this.provider1 = provider1; this.provider

在我的windows服务应用程序中,我需要在服务启动时使用配置解析组件。我使用温莎城堡作为我的IoC容器

应用程序看起来像:

public class RootComponent : IRootComponent {
    public RootComponent (IDataProvider1 provider1, IDataProvider2 provider2)
    {
        this.provider1 = provider1;
        this.provider2 = provider2;
    }

    ...
}

public class DataProvider1 : IDataProvider1
{
    ...

    public DataProvider1 (IDbHelper dbHelper)
    {
        this.dbHelper = dbHelper;
    }

    ...
}

public class DataProvider2 : IDataProvider2
{
    ...

    public DataProvider1 (IDbHelper dbHelper)
    {
        this.dbHelper = dbHelper;
    }

    ...
}

public interface IDbHelper
{
    IDbConnection GetNewConnection();
    DbParameter CreateDbParameter(string paramName, object paramValue);
    string GetCommandString(string commandName);
}

public class MsSqlDbHelper : IDbHelper
{
    ...

    public MsSqlDbHelper(string connectionString)
    {
        this.connectionString = connectionString;
    }

    ...
}

public class PostgreDbHelper : IDbHelper
{
    ...

    public PostgreDbHelper(string connectionString)
    {
        this.connectionString = connectionString;
    }

    ...
}
我想在服务构造函数和OnStart方法中注册依赖项,读取配置并基于配置解析正确的IDbHelper:

public partial class MyWindowsService : ServiceBase
{
    public MyWindowsService()
    {
        InitializeComponent();

        this.container = new WindsorContainer();
        RegisterDependencies();
    }

    private void RegisterDependencies()
    {
        container.Register(
            Classes.FromAssemblyInThisApplication().BasedOn<IRootComponent>().WithServiceFromInterface(), 
            Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider1>().WithServiceFromInterface(),
            Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider2>().WithServiceFromInterface(),
            Classes.FromAssemblyInThisApplication().BasedOn<IDbHelper>().WithServiceFromInterface()
                .ConfigureFor<MsSqlDbHelper>(
                    registration => {
                        registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString1")));
                        registration.Named("msSql");
                    })
                .ConfigureFor<PostgreDbHelper>(
                    registration => {
                        registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString2")));
                        registration.Named("postgreSql");
                    }));
    }

    protected override void OnStart(string[] args)
    {
        ResolveDependencies();
    }

    private void ResolveDependencies()
    {
        // Helper properties contain "msSql" or "postgreSql" value
        root = container.Resolve<IRootComponent>(Config.Provider1Helper, Config.Provider2Helper);
    }

    ...
}
公共部分类MyWindowsService:ServiceBase { 公共MyWindowsService() { 初始化组件(); this.container=新的WindsorContainer(); RegisterDependencies(); } 私有无效注册表依赖项() { 集装箱。登记( 类。FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface(), 类。FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface(), 类。FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface(), Classes.FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface() .配置( 注册=>{ registration.DependsOn(Dependency.OnValue(ConnectStringProvider.GetConnectionString(“connectString1”)); 注册。命名为(“msSql”); }) .配置( 注册=>{ registration.DependsOn(Dependency.OnValue(ConnectStringProvider.GetConnectionString(“connectString2”)); 注册。命名为(“postgreSql”); })); } 启动时受保护的覆盖无效(字符串[]args) { ResolveDependencies(); } 私有void ResolveDependencies() { //帮助器属性包含“msSql”或“postgreSql”值 root=container.Resolve(Config.Provider1Helper,Config.Provider2Helper); } ... } 我看到了三种解决已配置IDBhepper的方法:

  • 类型化工厂设施
  • 子容器
  • 实现IHandlerSelector

  • 最好的方法是什么?为什么?

    解决方案比我预期的要简单。动态参数是我所需要的:

    private void RegisterDependencies()
    {
        container.Register(
            Classes.FromAssemblyInThisApplication().BasedOn<IRootComponent>().WithServiceFromInterface(), 
            Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider1>().WithServiceFromInterface()
                .Configure(registration => registration.DynamicParameters((kernel, parameters) =>
                        {
                            IDbHelper dbHelper = kernel.Resolve<IDbHelper>(Config.Provider1Helper);
                            parameters.Add("dbHelper", dbHelper);
                            return k => k.ReleaseComponent(dbHelper);
                        })),
            Classes.FromAssemblyInThisApplication().BasedOn<IDataProvider2>().WithServiceFromInterface(),
                .Configure(registration => registration.DynamicParameters((kernel, parameters) =>
                        {
                            IDbHelper dbHelper = kernel.Resolve<IDbHelper>(Config.Provider2Helper);
                            parameters.Add("dbHelper", dbHelper);
                            return k => k.ReleaseComponent(dbHelper);
                        })),
            Classes.FromAssemblyInThisApplication().BasedOn<IDbHelper>().WithServiceFromInterface()
                .ConfigureFor<MsSqlDbHelper>(
                    registration => {
                        registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString1")));
                        registration.Named("msSql");
                    })
                .ConfigureFor<PostgreDbHelper>(
                    registration => {
                        registration.DependsOn(Dependency.OnValue<string>(ConnectStringProvider.GetConnectionString("connectString2")));
                        registration.Named("postgreSql");
                    }));
    }
    
    protected override void OnStart(string[] args)
    {
        // Helper properties should contain "msSql" or "postgreSql" value
        // take configuration from arguments
        Config.Provider1Helper = UseMsSql(args, 0) ? "msSql" : "postgreSql";
        Config.Provider2Helper = UseMsSql(args, 1) ? "msSql" : "postgreSql";
    
        ResolveDependencies();
    }
    
    private void ResolveDependencies()
    {
        root = container.Resolve<IRootComponent>();
    }
    
    private bool UseMsSql(string[] args, int argNumber)
    {
        ...
    }
    
    private void RegisterDependencies()
    {
    集装箱。登记(
    类。FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface(),
    Classes.FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface()
    .Configure(注册=>registration.DynamicParameters((内核,参数)=>
    {
    IDbHelper dbHelper=kernel.Resolve(Config.Provider1Helper);
    添加(“dbHelper”,dbHelper);
    返回k=>k.ReleaseComponent(dbHelper);
    })),
    类。FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface(),
    .Configure(注册=>registration.DynamicParameters((内核,参数)=>
    {
    IDbHelper dbHelper=kernel.Resolve(Config.Provider2Helper);
    添加(“dbHelper”,dbHelper);
    返回k=>k.ReleaseComponent(dbHelper);
    })),
    Classes.FromAssemblyInThisApplication().BasedOn().WithServiceFromInterface()
    .配置(
    注册=>{
    registration.DependsOn(Dependency.OnValue(ConnectStringProvider.GetConnectionString(“connectString1”));
    注册。命名为(“msSql”);
    })
    .配置(
    注册=>{
    registration.DependsOn(Dependency.OnValue(ConnectStringProvider.GetConnectionString(“connectString2”));
    注册。命名为(“postgreSql”);
    }));
    }
    启动时受保护的覆盖无效(字符串[]args)
    {
    //助手属性应包含“msSql”或“postgreSql”值
    //从参数获取配置
    Config.Provider1Helper=UseMsSql(args,0)?“msSql”:“postgreSql”;
    Config.Provider2Helper=UseMsSql(args,1)?“msSql”:“postgreSql”;
    ResolveDependencies();
    }
    私有void ResolveDependencies()
    {
    root=container.Resolve();
    }
    私有bool usemsql(字符串[]args,int argNumber)
    {
    ...
    }