2009-09-18 21 views
6

是否有可能使用不可變類型作爲.NET配置API的配置屬性?作爲配置屬性的不可變類型

比方說,我有一個不變的類型,稱爲MyClass的:

public class ImmutableClass 
{ 
    private readonly int value; 

    public ImmutableClass(int value) 
    { 
     this.value = value; 
    } 

    public int Value 
    { 
     get { return this.value; } 
    } 
} 

我想用這種類型的配置節配置屬性:

public class MyConfigurationSection : ConfigurationSection 
{ 
    [ConfigurationProperty("foo")] 
    public ImmutableClass Foo 
    { 
     get { return (ImmutableClass)base["foo"]; } 
     set { base["foo"] = value; } 
    } 
} 

當我這樣做,我可以對MyConfigurationSection進行序列化和反序列化,因爲它引發此異常:

System.Configurati on.ConfigurationErrorsException:屬性'標準'的值不能轉換爲字符串。該錯誤是:無法找到一個轉換器支持轉換爲字符串爲'FindCriterion'類型屬性'標準'的字符串。

如果我自ConfigurationElement派生ImmutableClass,我得到這個例外,當我嘗試序列化和反序列化配置部分:

System.Reflection.TargetInvocationException:異常被拋出通過調用的目標。 ---> System.Reflection.TargetInvocationException:調用的目標引發了異常。 ---> System.MissingMethodException:沒有爲此對象定義的無參數構造函數。

我完全控制ImmutableClass,所以我可以實現任何需要的接口。

有什麼辦法可以掛鉤到配置API,以便ImmutableClass可以用這種方式?

回答

1

您可能可以使用一些TypeConverters來幫助進程(鏈接到System.Configurations.ConfigurationConverter)。

真正的問題是,你爲什麼要造成自己這麼多麻煩?有些時候,最好能夠打好比打起來更好。該框架的某些部分是令人沮喪,如果你嘗試這樣做不是具體一個奠定了你其他任何方式....

+0

+1。謝謝,這工作得很好。我同意,在大多數情況下,隨着流動將更容易,這也是我通常做的,但這是一個特例... – 2009-09-18 14:29:21

+0

有用的信息...我實際上正在試驗不可變類型和xaml序列化。我希望類型轉換器也適用於我! – Will 2009-09-18 14:35:00

4

個人而言,我認爲你會做的更好,以在配置部分分離出來的數據 (看起來需要可變),以及如何在對象模型中表示它。沒有什麼能阻止你擁有兩種表示方式 - 一種是配置的簡單(DTO/POCO)版本,另一種是您的自定義版本(在這種情況下是不可變的),以便在您的應用中實際使用。

+0

我在大多數情況下都會同意,這也是我通常所做的,但這是一個特例。 – 2009-09-18 14:31:08

0

我會放棄那個詛咒,因爲這個想法被詛咒失敗。所有配置節處理程序必須具有默認(無參數)構造函數。你的不可變對象不是這種情況。

最簡單的解決方案是在配置和應用程序之間添加另一個抽象級別。您可以應用配置提供程序模式,並將配置節的「free for all」可變類轉換爲不可變類,然後由應用程序使用它。

我必須說這是應該如何使用配置部分。我知道有一個可靠的選項,但我從未使用過。

的代碼可能類似以下內容:

配置處理器

public class SectionHandler : ConfigurationSection 
{ 
    [ConfigurationProperty("foo")] 
    public MyObject ConfigurationValue 
    { 
    get { return (MyObject) this["foo"]; } 
    } 
} 

你已經得到了XML文件,併爲對象使用配置提供商模式消耗的配置值後應用程序中的配置。

配置供應商將可能是這個樣子:

public MyConfigurationProvider : IMyconfigurationProvider 
{ 

    public MyImmutabble ConfigurationValue 
    { 
    get 
    { 
     var configurationvalue = (MyObject) ConfigurationManager.GetSection("mySection"); 
     return new MyImmutable(configurationvalue.ConfigurationValue); 
    } 
    } 
} 

這是我要做的事,並一直擔任我至今。

希望它有幫助。

+0

在正常情況下,我完全同意你的意見,這也是我的常規做法,但這是一個特例。我只是按照Will的建議使它與TypeConverts一起工作,而且工作得很好,所以你最初的說法是不正確的。 – 2009-09-18 14:34:25

相關問題