我正在寻找摆脱 Windsor Xml 配置文件的方法。我只想保留必要的设置(主要是字符串)并将它们移动到 AppSettings。
有什么好的方法吗?最好不要在 AppSettings 和依赖项(ctor 参数)之间手动映射。
我不介意为此发生一些事情,但我想最小化实际业务问题解决应用程序的样板代码。
我正在寻找摆脱 Windsor Xml 配置文件的方法。我只想保留必要的设置(主要是字符串)并将它们移动到 AppSettings。
有什么好的方法吗?最好不要在 AppSettings 和依赖项(ctor 参数)之间手动映射。
我不介意为此发生一些事情,但我想最小化实际业务问题解决应用程序的样板代码。
您可以配置对 AppSettings 的依赖关系。
在您对不想注入配置对象发表评论后,我开始查看我的一些配置对象,SubDependancyResolvers
并且偶然我用谷歌搜索了如何在其中获取属性名称,SubDependancyResolver
然后我遇到了一个实际的实现。该项目是在mausch,由“杂项实验和其他yerbas”组成。我无法验证代码是否有效,但它遵循我的解析器的工作方式。
它们的实现包含一个属性,该属性应用于将配置中的应用程序设置映射到设置属性的设置类。另一种方法是拥有一个应用于要注入构造函数的属性的属性,并一起取消设置类:
public class AppSettingsAttribute: Attribute {}
public class AppSettingsResolver : ISubDependencyResolver
{
private readonly IKernel kernel;
public AppSettingsResolver(IKernel kernel)
{
this.kernel = kernel;
}
public object Resolve( CreationContext context, ISubDependencyResolver contextHandlerResolver, Castle.Core.ComponentModel model, DependencyModel dependency )
{
if( (
from constructor in model.Constructors
from dependencyModel in constructor.Dependencies
where dependencyModel == dependency
from parameterInfo in constructor.Constructor.GetParameters()
select parameterInfo ).Any( parameterInfo => parameterInfo.Name == dependency.DependencyKey ) )
{
var converter = (IConversionManager) kernel.GetSubSystem(SubSystemConstants.ConversionManagerKey);
return converter.PerformConversion(ConfigurationManager.AppSettings[dependency.DependencyKey], dependency.TargetType);
}
return null;
}
public bool CanResolve( CreationContext context, ISubDependencyResolver contextHandlerResolver, Castle.Core.ComponentModel model, DependencyModel dependency )
{
return (
from constructor in model.Constructors
from dependencyModel in constructor.Dependencies
where dependencyModel == dependency
from parameterInfo in constructor.Constructor.GetParameters()
where parameterInfo.Name == dependency.DependencyKey
select ( Attribute.GetCustomAttribute( parameterInfo, typeof(AppSettingsAttribute) ) != null )
).FirstOrDefault();
}
}
[ TestFixture ]
public class When_resolving_dependancies_from_the_app_settings_configuration_section
{
[ Test ]
public void Should_resolve_a_string_and_an_int()
{
var container = new WindsorContainer();
container.Kernel.Resolver.AddSubResolver(new AppSettingsResolver( container.Kernel ));
container.Register( Component.For<Dependent>() );
var dependent = container.Resolve<Dependent>();
dependent.Foo.Should().Be( "bar" );
dependent.Baz.Should().Be( 1 );
}
public class Dependent
{
public string Foo { get; private set; }
public int Baz { get; private set; }
public Dependent([AppSettings]string foo, [AppSettings]int baz)
{
Foo = foo;
Baz = baz;
}
}
}
为您的配置创建一个接口,然后有一个实现将ConfigurationManager.AppSettings
您注入到 Windsor 作为依赖项包装起来。
class SomeThingDependentOnSomeConfiguration
{
public SomeThingDependentOnSomeConfiguration(ISomeConfiguration config) { ... }
}
interface ISomeConfiguration
{
int SomeValue { get; }
string AnotherValue { get; }
}
class SomeConfigurationAppSettings : ISomeConfiguration
{
public int SomeValue
{
get
{
return Convert.ToInt32(ConfigurationManager.AppSettings["SomeValue"]);
}
}
public string AnotherValue
{
get
{
return ConfigurationManager.AppSettings["AnotherValue"];
}
}
}
这允许您稍后引入一个ConfigurationSection
(IMO 比应用程序设置更干净),或者如果您需要,您可以将其替换为使用硬编码值的类。
class SomeConfigurationConfigurationSections : ConfigurationSection, ISomeConfiguration
{
[ConfigurationProperty("SomeValue")]
public int SomeValue
{
get { return (int)this["SomeValue"]; }
}
[ConfigurationProperty("AnotherValue")]
public string AnotherValue
{
get { return (string)this["AnotherValue"]; }
}
}