1

DictionaryAdapter を使用して、asp.net Web サイトの appSettings セクションから設定を取得します。IoC 構成は、起動時に 1 回行われ、単一の Configuration.AppSettings オブジェクトを使用して、ゲッターを使用するすべての種類の異なるインターフェイスが登録されます。

 var dictionaryAdapterFactory = new DictionaryAdapterFactory();
        container.Register(
            Types
                .FromAssemblyNamed(assemblyName)
                .Where(t => t.Name.EndsWith("AppSettings"))
                .Configure(
                    component => component.UsingFactoryMethod(
                        (kernel, model, creationContext) =>
                        dictionaryAdapterFactory.GetAdapter(creationContext.RequestedType, ConfigurationManager.AppSettings))));

Web.config ファイルでホストされている appSettings セクションは正常に機能しますが、実行時に一部の設定を更新する場合に欠点があります。web.config ファイルなので、アプリ全体を再起動します。副作用として Web サイトを再起動することなく、実行時に構成を変更できるようにしたいと考えています。したがって、別のファイルに移動しました。

<appSettings configSource="AppSettings.config">

現在、ConfigurationManager.AppSettings["key"] を介して取得すると変更が反映されますが、DictionaryAdapter から動的インターフェイスを介してアクセスすると変更が反映されません。

ソースの変更を監視し、値をキャッシュしないように DA に指示する方法はありますか?

4

2 に答える 2

1

正確な答えは見つかりませんでしたが、回避策を見つけました。DA を ConfigurationManager に直接「バインド」する代わりに、CM をラップする単純なプロキシにバインドします。

public class AppSettingsProxy : NameValueCollection
{
    public override string Get(string name)
    {
        return ConfigurationManager.AppSettings[name];
    }

    public override string GetKey(int index)
    {
        return ConfigurationManager.AppSettings[index];
    }
}

次に、プロキシ インスタンスへのバインディングを変更します。

  container.Register(
            Types
                .FromAssemblyNamed(assemblyName)
                .Where(t => t.Name.EndsWith("AppSettings"))
                .Configure(
                    component => component.UsingFactoryMethod(
                        (kernel, model, creationContext) =>
                        dictionaryAdapterFactory.GetAdapter(creationContext.RequestedType, appSettingsProxy))));

上記は私にとってはうまくいきます。再起動せずに実行時に Web サイトの設定を変更できますが、値の変更は、設定インターフェイスを介して動的に生成されたプロキシを介して反映されるようになりました。

于 2013-06-21T13:42:38.070 に答える
0

DictionaryAdapter 自体は、既定では値をキャッシュしません。これは、それを証明する合格テストです。

    public interface IFoo
    {
        string Foo { get; set; } 
    }

    [Test]
    public void Adapter_does_not_cache_values_once_read()
    {
        var dict = new NameValueCollection { { "Foo", "Bar" } };

        var adapter = (IFoo)factory.GetAdapter(typeof(IFoo), dict);

        var value = adapter.Foo;

        dict["Foo"] = "Baz";
        var value2 = adapter.Foo;

        Assert.AreNotEqual(value, value2);
        Assert.AreEqual("Baz", value2);
    }

コードで値を自分でキャッシュしていませんか? テストで動作を再現できますか?

于 2013-06-21T04:41:26.573 に答える