2013-02-21 76 views
5

我正在研究簡化應用程序配置的庫。本質上,庫的使用者可以用屬性裝飾他們的配置類,或者用代碼聲明性地初始化這些設置。可以指定一個或多個來源來讀取/寫入配置屬性(訪問器)或從類繼承默認值。例如,以下內容:包含屬性中類型的庫中DI的最佳實踐

[ConfigurationNamespace(DefaultAccessors = new Type[] { typeof(AppSettingsAccessor) })] 
public class ClientConfiguration : Configuration<IClientConfiguration> 
{ 
    [ConfigurationItem(Accessors = new Type[] { 
     typeof((RegistryAccessor)) 
    })] 
    public bool BypassCertificateVerification { get; set; } 
} 

將相當於

var config = new Configuration<IClientConfiguration>(); 
config.SetDefaultAccessors(new[] { typeof(AppSettingsAccessor) }); 
config.SetPropertyAccessors(
    property: x => x.BypassCertificateVerification, 
    accessors: new[] { typeof(RegistryAccessor) } 
); 

的訪問者應對閱讀&從各種來源(的AppSettings,註冊表的.ini,等等,等等)編寫。我希望允許消費者擴展能力以滿足他們的需求。我想保持它IoC容器不可知論者。 Type []約束是給我的,因爲由於編譯時和運行時問題,我無法在屬性中指定類型。

有沒有辦法有用於實例默認這些機制(例如,基於Activator.CreateInstance東西),而且還允許消費代碼來實例化這些訪問在運行時不使用服務定位器/依賴解析器模式?我一直在閱讀很多關於爲什麼服務定位器/依賴關係解析器模式是一個邪惡的反模式,但我找不出一個更好的工具。我使用依賴解析器查看MVC框架和SignalR庫。他們是100%的時間還是這個邊緣案例?據我所知,抽象工廠模式不會削減它,因爲它不喜歡類型參數。

在這種特殊情況下,基於屬性的配置將比聲明式方法更有用,所以我不想放棄配置屬性(這將允許我將Type更改爲IConfigurationAccessor並切換到工廠方法)。

回答

5

從DSL上的工作中,我們知道將API與其他表達模式分離爲基本的語義模型是很重要的。在這種情況下,Configuration<T> API在我看來就像是語義模型。沒有理由在基於屬性的DSL之後對語義模型進行建模。像這樣會使更多的意義對我說:

var config = new Configuration<IClientConfiguration>(); 
config.DefaultAccessors.Add(new AppSettingsAccessor()); 
config.PropertyAccessorsFor(x => x.BypassCertificateVerification) 
    .Add(new RegistryAccessor()); 

我也想改變基於屬性的模型是純聲明:

[AppSettingsConfiguration] 
public class ClientConfiguration : Configuration<IClientConfiguration> 
{ 
    [RegistryConfiguration] 
    public bool BypassCertificateVerification { get; set; } 
} 

現在你「只有」需要搞清楚一個從自適應模型轉換爲語義模型的方式。

基本上就像其他序列化閱讀器:讀取數據,並從類型註釋中提示如何閱讀它。這基本上是遞歸遍歷數據結構,並且對於每個節點,您都需要創建一個Accessor。

假設所有訪問者的實現像IAccessor的接口,這可以由可擴展與抽象工廠

public interface IAccessorFactory 
{ 
    IAccessor CreateAccessor(ConfigurationAttribute configurationAttribute); 
} 

其實,這是更具體叫產品交易不太廣爲人知的設計模式描述在PLoPD4,但由於大多數人不知道這種模式,我們只能稱它爲抽象工廠 - it's not a Service Locator,因爲它不返回一個無界的類型 - 它只會返回IAccessor實例。

+0

我也在考慮DSL。我想到了一些沿着這些方向的東西,但是最終你會得到一個未加解析dsl的屬性,這個屬性幾乎沒有意義。 – 2013-02-22 16:25:58