如何告诉dictionaryAdapter从ConfigurationManager.AppSettings中查看更改?

时间:2013-06-18 12:03:12

标签: castle appsettings configsource castle-dictionaryadapter

我使用DictionaryAdapter从我的asp.net网站的appSettings部分检索设置。 IoC配置在启动时完成一次,使用单个Configuration.AppSettings对象注册具有getter的各种不同接口:

 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文件,所以重新启动整个应用程序。我希望能够在运行时修改配置而无需重新启动网站作为副作用。因此,我进入了单独的文件:

<appSettings configSource="AppSettings.config">

现在,通过ConfigurationManager.AppSettings [“key”]检索更改时会反映出更改,但在访问时不会反映这些更改 DictionaryAdapter的动态接口。

有没有办法告诉DA监视源中的更改而不是缓存值?

2 个答案:

答案 0 :(得分: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];
    }
}

然后jus tchange绑定到我的代理实例:

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

以上对我有用。虽然我可以在运行时修改我的网站设置而不重启,但现在通过我的设置界面上的动态生成的代理反映了值的变化。

答案 1 :(得分: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);
    }

您确定自己没有在代码中自行缓存价值吗?你能在测试中重现这种行为吗?