使用Castle容器中的已注册组件为另一个组件提供依赖关系

时间:2015-06-18 13:31:21

标签: c# .net dependency-injection castle-windsor

我有一个Castle Windsor容器注册课程如下......

public class WindsorInstaller : IWindsorInstaller
{
    public void Install(IWindsorContainer container, IConfigurationStore store)
    {           
        container.Register(Component.For<IConfigProvider>()
            .ImplementedBy<ConfigProvider>()
            .LifeStyle.Singleton);

        container.Register(Component.For<IDbRepository>()
            .ImplementedBy<DbRepository>()
            .LifeStyle.Singleton                
            .DependsOn(Dependency.OnValue(
                "connectionString", 
                // -- Somehow call GetConfig() on the IConfigProvider --
        )));                
    }
}

DbRepository需要在对象构造中传递连接字符串。但是,该连接字符串实际上是由IConfigProvider提供的。

是否有可能让Castle Windsor以某种方式解析IConfigProvider并调用GetConfig方法?

如果这不是一个好主意,请打开其他选项。

2 个答案:

答案 0 :(得分:2)

您可以使用DynamicParameters来完成此任务:

container.Register(Component.For<IDbRepository>()
    .ImplementedBy<DbRepository>()
    .LifeStyle.Singleton                
    .DynamicParameters((k,d) => 
    {
        var configProvider = k.Resolve<IConfigProvider>();
        d["connectionString"] = configProvider.GetConfig();
    }
)));      

来自文档:

  

DynamicParameters使用在组件分辨率管道的最开始调用的委托。

换句话说,您将在解析组件之前检索连接字符串。

答案 1 :(得分:0)

你可能想要结帐城堡温莎的工厂设施。

https://visualstudiomagazine.com/articles/2011/12/01/windsor-beyond-dependency-injection.aspx

编辑:

以下是您想要做的一个例子..

http://joseoncode.com/2011/01/09/windsor-isubdependencyresolver-example/

实施AbstractFacility,它将解析您的连接字符串

    public class DependenciesFromAppSettings : AbstractFacility
{
    protected override void Init()
    {
        var dic = ConfigurationManager
             .AppSettings
             .AllKeys
             .ToDictionary(k => k, k => ConfigurationManager.AppSettings[k]);

        Kernel.Resolver.AddSubResolver(new DependenciesFromAppSettingsResolver(dic));
    }
}

实施ISubDependencyResolver

    public class DependenciesFromAppSettingsResolver : ISubDependencyResolver
{
    private readonly IDictionary<string, string> webConfig;

    public DependenciesFromAppSettingsResolver(IDictionary<string, string> webConfig)
    {
        /// you can pass in your configprovider object here (or similar)
        this.webConfig = webConfig;
    }

    public bool CanResolve(Castle.MicroKernel.Context.CreationContext context, 
        ISubDependencyResolver contextHandlerResolver, 
        Castle.Core.ComponentModel model, 
        Castle.Core.DependencyModel dependency)
    {
        //make sure your connectionstring has value
    }

    public object Resolve(Castle.MicroKernel.Context.CreationContext context, 
        ISubDependencyResolver contextHandlerResolver, 
        Castle.Core.ComponentModel model, 
        Castle.Core.DependencyModel dependency)
    {
        //resolve your connectionstring here
    }
}

您的回购符如下所示:

    public class MyRepo 
{
    public MyRepo(string connectionString)
    {

    }

}

您的城堡Windsor容器将如下所示(即添加设施):

IWindsorContainer container = new WindsorContainer();
        ///Register your ConfigProvider here
        container.AddFacility<DependenciesFromAppSettings>();
        container.Register(Component.For<MyRepo>());

请注意,代码是从上面的链接借来的。

希望这有帮助