我使用DictionaryAdapter从我的asp.net网站的appSettings部分检索设置。IoC配置在启动时完成一次,并且使用单个配置注册带有getter的各种不同接口。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中的appSettings部分。配置文件工作得很好,但它有它的缺点,当我想在运行时更新一些设置。因为它是网络。配置文件,整个应用程序重新启动。我想能够修改配置在运行时不重新启动网站作为副作用。因此,我移动到单独的文件:
<appSettings configSource="AppSettings.config">
现在,在通过ConfigurationManager检索更改时将反映更改。AppSettings["key"],但在访问时不会反映来自DictionaryAdapter的动态接口
是否有任何方法可以告诉DA监视源中的更改而不缓存值?
虽然我没有找到确切的答案,但我找到了一个解决方法。我没有将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))));
以上内容适用于我。虽然我可以在运行时修改我的网站设置而无需重新启动,但现在的值变化是通过动态生成的代理在我的设置界面上反映出来的。
默认情况下,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);
}
你确定自己没有在代码中缓存这个值吗?你能在测试中重现这种行为吗?