2

Windsor Xml 構成ファイルを削除する方法を探しています。必要な設定(ほとんど文字列)だけ残してAppSettingsに移動したい。

それを行う良い方法はありますか?できれば、AppSettings と依存関係 (ctor パラメーター) の間の手動マッピングを使用しないでください。

これを実現するために何かを実装してもかまいませんが、実際のビジネス問題解決アプリケーションのボイラープレート コードを最小限に抑えたいと考えています。

4

3 に答える 3

6

AppSettings への依存関係を構成できます。

于 2012-06-09T10:38:26.550 に答える
3

サブ依存関係リゾルバーを使用して値を挿入する

構成オブジェクトを挿入したくないというコメントの後、私は自分のいくつかを調べ始めましたSubDependancyResolvers。偶然にも、でプロパティ名を取得する方法をグーグルで検索しSubDependancyResolver、実際の実装に出くわしました。このプロジェクトは、「その他の実験とその他のイェルバ」で構成されています。コードが機能することを確認できませんが、リゾルバーがどのように機能するかに従います。

それらの実装は、構成内のアプリ設定を設定プロパティにマップする設定クラスに適用する属性で構成されます。別の方法として、コンストラクターに挿入するプロパティに適用する属性を設定し、設定クラスをすべて削除することもできます。

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 に答える