2

我正在寻找摆脱 Windsor Xml 配置文件的方法。我只想保留必要的设置(主要是字符串)并将它们移动到 AppSettings。

有什么好的方法吗?最好不要在 AppSettings 和依赖项(ctor 参数)之间手动映射。

我不介意为此发生一些事情,但我想最小化实际业务问题解决应用程序的样板代码。

4

3 回答 3

6

您可以配置对 AppSettings 的依赖关系

于 2012-06-09T10:38:26.550 回答
3

使用子依赖解析器注入值

在您对不想注入配置对象发表评论后,我开始查看我的一些配置对象,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;
        }
    }
}
于 2012-06-08T15:45:27.167 回答
0

使用带有特定配置类的属性注入

为您的配置创建一个接口,然后有一个实现将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"]; }
    }
}
于 2012-06-08T13:09:10.690 回答