C# 温莎城堡使用工厂法和生活方式
考虑到castle windsor 3.4.0中的以下实施:C# 温莎城堡使用工厂法和生活方式,c#,.net,inversion-of-control,castle-windsor,ioc-container,C#,.net,Inversion Of Control,Castle Windsor,Ioc Container,考虑到castle windsor 3.4.0中的以下实施: public class ExampleInstaller : IWindsorInstaller { public void Install(IWindsorContainer container, IConfigurationStore store) { container.Register(Component.For<FailoverDatabaseConnectionExecutor>
public class ExampleInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<FailoverDatabaseConnectionExecutor>()
.ImplementedBy<FailoverDatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<DatabaseConnectionExecutor>()
.ImplementedBy<DatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
UsingFactoryMethod(CreateDatabaseConnectionExecutor)
.LifestyleTransient()
.IsDefault());
}
private static IDatabaseConnectionExecutor CreateDatabaseConnectionExecutor(IKernel kernel)
{
var configurationRepository = kernel.Resolve<IConfigurationRepository>();
return configurationRepository.GetSetting(ConfigurationSettings.DatabaseFailoverEnabled, () => false)
? (IDatabaseConnectionExecutor)kernel.Resolve<FailoverDatabaseConnectionExecutor>()
: kernel.Resolve<DatabaseConnectionExecutor>();
}
}
从SomeConnectionService中删除IDisposable将正确注入依赖链
有人知道为什么在castle windsor中会出现这种情况吗?这里的问题是。UsingFactoryMethod()返回一个已注册的组件,然后再次尝试注册它 您可以尝试将.Named()添加到第一次和第二次注册中
container.Register(Component.For<IDatabaseConnectionExecutor>()
.ImplementedBy<FailoverDatabaseConnectionExecutor>()
.Named('FailoverExecutor')
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
.ImplementedBy<DatabaseConnectionExecutor>()
.Named('NormalExecutor')
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
UsingFactoryMethod(CreateDatabaseConnectionExecutor)
.LifestyleTransient()
.IsDefault());
container.Register(Component.For())
.由()实施
.Named('FailoverExecutor')
.生活方式(暂时的);
container.Register(Component.For())
.由()实施
.Named('NormalExecutor')
.生活方式(暂时的);
container.Register(Component.For())
使用FactoryMethod(CreateDatabaseConnectionExecutor)
.生活方式
.IsDefault());
在factory方法中,然后使用名称解析组件
return configurationRepository.GetSetting(ConfigurationSettings.DatabaseFailoverEnabled, () => false)
? kernel.Resolve<IDatabaseConnectionExecutor>("FailoverExecutor")
: kernel.Resolve<IDatabaseConnectionExecutor>("NormalExecutor");
返回configurationRepository.GetSetting(ConfigurationSettings.DatabaseFailoverEnabled,()=>false)
? kernel.Resolve(“FailoverExecutor”)
:kernel.Resolve(“NormalExecutor”);
在研究了温莎城堡的一些代码之后,似乎很明显,在跟踪标记为退役的物体方面存在问题
我们通过切换使用IHandlerSelector克服了这个问题。这允许我们在运行时根据配置设置动态选择依赖项
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IDatabaseConnectionExecutor>()
.ImplementedBy<FailoverDatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
.ImplementedBy<DatabaseConnectionExecutor>()
.LifestyleTransient());
var configuration = container.Resolve<IConfigurationRepository>();
container.Kernel.AddHandlerSelector(new DatabaseExecutorHandlerSelector(configuration));
container.Release(configuration);
}
}
public class DatabaseExecutorHandlerSelector : IHandlerSelector
{
private readonly IConfigurationRepository configurationRepository;
public DatabaseExecutorHandlerSelector(IConfigurationRepository configurationRepository)
{
this.configurationRepository = configurationRepository;
}
public bool HasOpinionAbout(string key, Type service)
{
return service == typeof(IDatabaseConnectionExecutor);
}
public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
{
var failoverEnabled = configurationRepository.GetSetting(ConfigurationSettings.BagDatabaseFailoverEnabled, () => false);
var implementationToUse = failoverEnabled ?
typeof(FailoverDatabaseConnectionExecutor) :
typeof(DatabaseConnectionExecutor);
return handlers.First(x => x.ComponentModel.Implementation == implementationToUse);
}
}
公共类存储安装程序:IWindsorInstaller
{
public void安装(IWindsorContainer、IConfigurationStore)
{
container.Register(Component.For())
.由()实施
.生活方式(暂时的);
container.Register(Component.For())
.由()实施
.生活方式(暂时的);
var配置=container.Resolve();
container.Kernel.AddHandlerSelector(新数据库执行器HandlerSelector(配置));
容器。释放(配置);
}
}
公共类数据库ExecutorHandlerSelector:IHandlerSelector
{
专用只读IConfigurationRepository configurationRepository;
公共数据库ExecutorHandlerSelector(IConfigurationRepository configurationRepository)
{
this.configurationRepository=configurationRepository;
}
公共bool HasOpinionAbout(字符串键,类型服务)
{
返回服务==typeof(IDatabaseConnectionExecutor);
}
公共IHandler SelectHandler(字符串键,类型服务,IHandler[]处理程序)
{
var failoverEnabled=configurationRepository.GetSetting(ConfigurationSettings.BagDatabaseFailoverEnabled,()=>false);
var implementationToUse=故障过可控制?
类型(FailoverDatabaseConnectionExecutor):
类型(数据库连接执行器);
首先(x=>x.ComponentModel.Implementation==implementationToUse);
}
}
在从工厂方法返回之前,请尝试释放()配置存储库。在使用Castle时,您应该养成为您解析的所有内容显式调用Release()的习惯。
public class RepositoriesInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.Register(Component.For<IDatabaseConnectionExecutor>()
.ImplementedBy<FailoverDatabaseConnectionExecutor>()
.LifestyleTransient());
container.Register(Component.For<IDatabaseConnectionExecutor>()
.ImplementedBy<DatabaseConnectionExecutor>()
.LifestyleTransient());
var configuration = container.Resolve<IConfigurationRepository>();
container.Kernel.AddHandlerSelector(new DatabaseExecutorHandlerSelector(configuration));
container.Release(configuration);
}
}
public class DatabaseExecutorHandlerSelector : IHandlerSelector
{
private readonly IConfigurationRepository configurationRepository;
public DatabaseExecutorHandlerSelector(IConfigurationRepository configurationRepository)
{
this.configurationRepository = configurationRepository;
}
public bool HasOpinionAbout(string key, Type service)
{
return service == typeof(IDatabaseConnectionExecutor);
}
public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
{
var failoverEnabled = configurationRepository.GetSetting(ConfigurationSettings.BagDatabaseFailoverEnabled, () => false);
var implementationToUse = failoverEnabled ?
typeof(FailoverDatabaseConnectionExecutor) :
typeof(DatabaseConnectionExecutor);
return handlers.First(x => x.ComponentModel.Implementation == implementationToUse);
}
}