1

我使用DictionaryAdapter從我的asp.net網站的appSettings部分檢索設置。 的IOC配置只進行一次,在啓動時間和各種不同接口的getter正在使用單Configuration.AppSettings註冊的對象:如何告訴dictionaryAdapter監視ConfigurationManager.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文件,整個應用程序重新啓動。我希望能夠在運行時修改配置,而不必重新啓動網站作爲副作用。因此,我移到單獨的文件:

<appSettings configSource="AppSettings.config"> 

現在,通過ConfigurationManager.AppSettings檢索它們時變化被反映[「鍵」],但通過從DictionaryAdapter 動態接口訪問時,他們沒有反射。

有什麼辦法可以告訴DA來觀察源代碼中的變化,而不是緩存這些值嗎?

回答

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]; 
    } 
} 

然後強制tchange綁定到我的代理實例:

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

以上爲我工作。儘管我可以在運行時修改我的網站設置而無需重新啓動,但現在,通過我的設置界面上動態生成的代理服務器可以反映更改值。

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); 
    } 

您確定自己沒有在代碼中緩存自己的值嗎?你可以在測試中重現行爲嗎?

+0

事實上,這可以發揮作用。如果你在相同的測試中綁定到ConfigurationManager.AppSettings,它也會起作用。然而,重點在於如果您在網站上下文中操作並更改appsettings.config文件中的值,而不是通過代碼(如示例中所示),則更改不會被反映出來。我不確定問題出在哪裏,無論是DA還是CM。我在單元測試中遇到麻煩來重現我的場景,因爲這涉及到更改配置文件(而不是通過代碼收集)以及Web環境。 –

+0

無論如何,我找到了一個簡單的解決方法來解決我的問題,這個工作非常好,所以我會保持原樣。無論如何,非常感謝,因爲您的帖子有助於解決我的問題。 –