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

C# 使用Castle容器中已注册的组件为另一个组件提供依赖项,c#,.net,dependency-injection,castle-windsor,C#,.net,Dependency Injection,Castle Windsor,我有一个温莎城堡集装箱注册课程如下 public class WindsorInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Component.For<IConfigProvider>() .Impl

我有一个温莎城堡集装箱注册课程如下

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 --
        )));                
    }
}
公共类WindsorInstaller:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{           
container.Register(Component.For())
.由()实施
(1,生活方式,单身人士),;
container.Register(Component.For())
.由()实施
.单身汉
.DependsOn(Dependency.OnValue(
“连接字符串”,
//--以某种方式在IConfigProvider上调用GetConfig()--
)));                
}
}
DbRepository需要在对象构造时传入一个连接字符串。但是,该连接字符串实际上是由IConfigProvider提供的

现在是否可以让Castle Windsor以某种方式解析IConfigProvider并调用GetConfig方法

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

您可以使用以下方法完成此操作:

container.Register(Component.For<IDbRepository>()
    .ImplementedBy<DbRepository>()
    .LifeStyle.Singleton                
    .DynamicParameters((k,d) => 
    {
        var configProvider = k.Resolve<IConfigProvider>();
        d["connectionString"] = configProvider.GetConfig();
    }
)));      
container.Register(Component.For())
.由()实施
.单身汉
.动态参数((k,d)=>
{
var configProvider=k.Resolve();
d[“connectionString”]=configProvider.GetConfig();
}
)));      
从文件中:

DynamicParameters与委托一起工作,委托在组件解析管道的最开始处被调用


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

您可能需要签出castle Windsor的类型化工厂设施

编辑:

下面是一个你想做什么的例子

实现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));
    }
}
实现isubdependencyrolver

    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
    }
}
您的castle Windsor集装箱如下所示(即添加设施):

IWindsorContainer=new WindsorContainer();
///在此处注册您的ConfigProvider
container.AddFacility();
container.Register(Component.For());
注意,代码是从上面的链接中借用的

希望这有帮助

    public class MyRepo 
{
    public MyRepo(string connectionString)
    {

    }

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