2011-08-27 61 views
3

我想要做的是有一個多功能的設置類,我可以在複合應用程序中使用。我添加的特徵和部件,並使用MEF &棱鏡構成應用我想有自動加載每個模塊的設置接口到一個窗口(使用Prism & MEF)我將如何爲應用程序創建複合設置?

有許多不同的一個設置窗口處理設置,並吸引我的一個辦法是沿着下面的內容:

public class AppData : ApplicationSettingsBase 
{ 
    [UserScopedSetting()] 
    [DefaultSettingValue("true")] 
    public bool Clipboard 
    { 
    get { return ((bool)this["Clipboard"]); } 
    set { this["Clipboard"] = (bool)value; } 
    } 
} 

這使我可以設置默認值,我假設,如果應用程序沒有找到.settings然後文件它會創建一個默認值。不過,我需要爲每個模塊設置部分編寫一堆自定義代碼,併爲每個模塊創建一個獨特的對話框,或嘗試使用設置管理器手動加載它們。

有一些設置會有也有多個值,看起來上面的例子不能滿足這個要求。如果我有一個存儲了一個列表的設置,該怎麼辦?例如,如果我的設置是ValidBlock,並且在開始時有兩個可能有效的塊,但將來可能需要添加更多?你可以有一個設置是一個列表,並指定該設置的多個默認值?

因此,如果創建一個Isettings接口,以某種方式使用ApplicationSettingsBase,以便我可以使用MEF在目錄中的所有模塊中查找所有Isettings實現,然後爲每個實現找到它們,在Isettings接口中,我可以擁有一些基本屬性,例如Name以及在MEF WPF窗口中標記和描述模塊所需的其他內容。

我唯一不喜歡的其他事情是字符串和屬性到處都是。有沒有辦法以流利的方式處理設置?我沿着具有ISettings實現的線,你會明確地編寫一個設置類似如下的思考:

public class AppData : ISettings 
{ 
    Setting Clipboard = new Setting(); 
    Clipboard.Scope = SettingScope.User; 
    Clipboard.SettingType = List<String>; 

    List<String> DefaultClipboards = new List<String>(); 
    DefaultClipboards.Add("FoxClipboard"); 
    Clipboard.DefaultSetting = DefaultClipboards; 
} 

我知道上面是不完全正確的語法,我不認爲Clipboard.SettingType會持有很多水,但它會給我一個想法。所以如果這樣的事情可以實現,同時保持創建一個設置文件,如果一個人失蹤,這將是理想的。與此類似,MEF可以找到所有的ISettings實現併爲每個實現創建一個選項卡,然後根據代碼中的設置添加每個設置。

這是正確的軌道嗎?有沒有我錯過的框架或項目來處理我的目標?我認爲可能比我所概述的更好?

我相信這個問題已經出現在複合應用程序開發中,但我還沒有找到概述這種情況的框架或答案。

我已經能夠創建一個鬆散耦合的複合應用程序和動態使用MEF &棱鏡線了我的模塊,但我一直沒能找到一種令人滿意的方式來處理的複合方式設置。

回答

1

我在工作中處理了一個類似的應用程序。我們進一步傾向於第二個想法,那裏只有一個基本設置界面「ISettings」,我們用於MEF組合。

我們創建了一個自定義導出提供程序來處理加載設置,並且有一個管理器使用一些序列化程序來保存設置。

對於用戶界面,我們使用面向用戶的設置的模塊也會導出一個「設置工作區」,我們將加載到設置UI中。使用反射,我們編寫了一個方法,它將設置對象的深層副本,以便我們可以直接對克隆對象執行mvvm綁定(用於取消功能),以及獲取對象並將其複製回來。

反思是爲了在不爲每個設置對象編寫代碼的情況下允許通用的克隆/複製。

此外,我們仍然喜歡到今天進行數據模型綁定的一件事是「INotifyPropertyChanged」接口。我們的基礎ISettings對象需要它。這不僅允許設置用戶界面直接綁定到設置並監聽更改,但是當我們點擊應用或確定時,我們所有需要設置的數據模型都會註冊爲prop更改事件,因此當設置發生時它們都會自動得到通知改變。

如果您計劃執行通知路線,請檢出Property Observer。此應用程序已部署,我仍然覺得我們的設置框架非常成功。

如果您需要,我可以提供某些領域的更多細節。

希望這會有所幫助!

1

聲明:我沒有使用ApplicationSettingsBase的自定義實現的經驗,所以我無法協助其實際實現,也沒有積極地說這種方法可行。但是,我建議可能是一個值得探索的路徑,如果你真的想使用ApplicationSettingsBase。

首先,設置不能繼承 ApplicationSettingsBase,因爲接口只能繼承其他接口。

我的建議是創建一個用ISettings實例參數化的自定義ApplicationSettingsBase實現。這樣,無論何時從組件中接收一個ISettings,都可以實例化一個新的CustomAppSettings(見下文)並將其與組件關聯。

由於ApplicationSettingsBase使用字符串到對象的鍵值對映射,我提出了一個相同的接口。

public interface ISettings 
{ 
    Dictionary<string,object> Values{ get; set; } 

    public object GetDefaultValue(string key); 

    // Whatever else you might need 
} 

public class CustomAppSettings : ApplicationSettingsBase 
{ 
    public ISettings Settings { get; set; } 

    public override object this[string propertyName] 
    { 
     get 
     { 
      return this.Settings.Values[propertyName]; 
     } 
     set 
     { 
      this.Settings.Values[propertyName] = value; 
     } 
    } 

    // There will be more implementation work for this class I'm sure 
} 

此外,您需要ISetting實例的序列化機制。

編輯:修正了一些代碼語法錯誤

相關問題