C# 可扩展.NET配置

C# 可扩展.NET配置,c#,.net,oop,design-patterns,C#,.net,Oop,Design Patterns,我想分发一个带有ConfigurationSection的DLL,如下所示: public class StandardConfiguration : ConfigurationSection { public static StandardConfiguration GetInstance() { return (StandardConfiguration)ConfigurationManager.GetSection("customConfigSection"

我想分发一个带有
ConfigurationSection
的DLL,如下所示:

public class StandardConfiguration : ConfigurationSection
{
    public static StandardConfiguration GetInstance()
    {
        return (StandardConfiguration)ConfigurationManager.GetSection("customConfigSection");
    }

    [ConfigurationProperty("childConfig")]
    public StandardChildConfig ChildConfig
    {
        get { return (StandardChildConfig)this["childConfig"]; }
        set { this["childConfig"] = value; }
    }
}

public class StandardChildConfig : ConfigurationElement
{
    [ConfigurationProperty("p1")]
    public string P1
    {
        get { return (string)this["p1"]; }
        set { this["p1"] = value; }
    }
}
public class StandardConfiguration<TChildConfig> : ConfigurationSection
    where TChildConfig : StandardChildConfig
{
    [ConfigurationProperty("childConfig")]
    public TChildConfig ChildConfig
    {
        get { return (TChildConfig)this["childConfig"]; }
        set { this["childConfig"] = value; }
    }
}

public class StandardChildConfig : ConfigurationElement
{
    [ConfigurationProperty("p1")]
    public string P1
    {
        get { return (string)this["p1"]; }
        set { this["p1"] = value; }
    }
}
我想使
ConfigurationSection
及其子
ConfigElement
可继承。这可以使用类型参数完成,如下所示:

public class StandardConfiguration : ConfigurationSection
{
    public static StandardConfiguration GetInstance()
    {
        return (StandardConfiguration)ConfigurationManager.GetSection("customConfigSection");
    }

    [ConfigurationProperty("childConfig")]
    public StandardChildConfig ChildConfig
    {
        get { return (StandardChildConfig)this["childConfig"]; }
        set { this["childConfig"] = value; }
    }
}

public class StandardChildConfig : ConfigurationElement
{
    [ConfigurationProperty("p1")]
    public string P1
    {
        get { return (string)this["p1"]; }
        set { this["p1"] = value; }
    }
}
public class StandardConfiguration<TChildConfig> : ConfigurationSection
    where TChildConfig : StandardChildConfig
{
    [ConfigurationProperty("childConfig")]
    public TChildConfig ChildConfig
    {
        get { return (TChildConfig)this["childConfig"]; }
        set { this["childConfig"] = value; }
    }
}

public class StandardChildConfig : ConfigurationElement
{
    [ConfigurationProperty("p1")]
    public string P1
    {
        get { return (string)this["p1"]; }
        set { this["p1"] = value; }
    }
}
下面是扩展配置的场景:

<?xml version="1.0"?>
<configuration>
    <configSections>
        <section
            name="customConfig"
            type="WebsiteTemplate.Extended.Config.ExtendedConfigruation, WebsiteTemplate.Extended"
        />
    </configSections>
    <customConfig baseProp1="a" extendedProp1="c">
        <childConfig baseProp2="b" extendedProp2="d" />
    </customConfig>
</configuration>


在第二个实例中
标准配置。GetInstance()
没有任何意义,因为
标准配置是通用的。您必须使用
StandardConfiguration.GetInstance().ChildConfig.P1

您可能可以执行以下操作:

public class StandardConfigurationBase : ConfigurationSection
{
    public static StandardConfigurationBase GetInstance()
    {
        return (StandardConfigurationBase) ConfigurationManager.GetSection("customConfigSection");
    }

    [ConfigurationProperty("childConfig")]
    public StandardChildConfig ChildConfig
    {
        get { return (StandardChildConfig) this["childConfig"]; }
        set { this["childConfig"] = value; }
    }
}

public class StandardConfiguration<TChildConfig> : StandardConfigurationBase
where TChildConfig : StandardChildConfig
{
    [ConfigurationProperty("childConfig")]
    public new TChildConfig ChildConfig
    {
        get { return (TChildConfig)this["childConfig"]; }
        set { this["childConfig"] = value; }
    }
}
public class StandardChildConfig : ConfigurationElement
{
    [ConfigurationProperty("p1")]
    public string P1
    {
        get { return (string)this["p1"]; }
        set { this["p1"] = value; }
    }
}
公共类标准配置库:配置部分
{
公共静态StandardConfigurationBase GetInstance()
{
return(StandardConfigurationBase)ConfigurationManager.GetSection(“customConfigSection”);
}
[ConfigurationProperty(“childConfig”)]
公共标准ChildConfig ChildConfig
{
获取{return(StandardChildConfig)this[“childConfig”];}
设置{this[“childConfig”]=value;}
}
}
公共类StandardConfiguration:StandardConfigurationBase
其中TChildConfig:StandardChildConfig
{
[ConfigurationProperty(“childConfig”)]
公共新TChildConfig ChildConfig
{
获取{return(TChildConfig)this[“childConfig”];}
设置{this[“childConfig”]=value;}
}
}
公共类StandardChildConfig:ConfigurationElement
{
[配置属性(“p1”)]
公共字符串P1
{
获取{返回(字符串)this[“p1”];}
设置{this[“p1”]=value;}
}
}
然后在不知道子对象的特定类型时访问该子对象:

    StandardConfigurationBase b = new StandardConfiguration<StandardChildConfig>();
    StandardChildConfig x = StandardConfigurationBase.GetInstance().ChildConfig;
StandardConfigurationBase b=新的StandardConfiguration();
StandardChildConfig x=StandardConfigurationBase.GetInstance().ChildConfig;
但是,我不清楚这样做的真正价值。

我的问题的“答案”是将基本配置分解为一个带有类型参数和接口的抽象类

下面显示了BaseLib.dll中定义的内容。有默认配置和默认子配置

接口和abstract类

public interface IAppConfig
{
    string AppProp1 { get; }
    SubConfig SubConfig { get; }
}

public abstract class BaseAppConfig<TSubConfig> : ConfigurationSection, IAppConfig
    where TSubConfig : SubConfig
{
    [ConfigurationProperty("appProp1")]
    public string AppProp1
    {
        get { return (string)this["appProp1"]; }
        set { this["appProp1"] = value; }
    }

    [ConfigurationProperty("subConfig")]
    public TSubConfig SubConfig
    {
        get { return (TSubConfig)this["subConfig"]; }
        set { this["subConfig"] = value; }
    }

    // Implement the interface
    string IAppConfig.AppProp1 { get { return this.AppProp1; } }
    SubConfig IAppConfig.SubConfig { get { return this.SubConfig; } }
}
public class AppConfig : BaseAppConfig<SubConfig>
{
    const string SECTION_KEY = "AppConfig";

    public static IAppConfig Instance
    {
        get { return (IAppConfig)ConfigurationManager.GetSection(SECTION_KEY); }
    }
}

public class SubConfig : ConfigurationElement
{
    [ConfigurationProperty("supProp1")]
    public string SubProp1
    {
        get { return (string)this["supProp1"]; }
        set { this["supProp1"] = value; }
    }
}
public class ExtAppConfig : BaseAppConfig<ExtSubConfig>
{
    public static ExtAppConfig Instance
    {
        get { return (ExtAppConfig)AppConfig.Instance; }
    }

    [ConfigurationProperty("extAppProp1")]
    public string ExtAppProp1
    {
        get { return (string)this["extAppProp1"]; }
        set { this["extAppProp1"] = value; }
    }
}

public class ExtSubConfig : SubConfig
{
    [ConfigurationProperty("extSubProp1")]
    public string ExtSubProp1
    {
        get { return (string)this["extSubProp1"]; }
        set { this["extSubProp1"] = value; }
    }
}
下面显示了ExtLib.dll中定义的内容。配置和子配置都被扩展

扩展实施

public interface IAppConfig
{
    string AppProp1 { get; }
    SubConfig SubConfig { get; }
}

public abstract class BaseAppConfig<TSubConfig> : ConfigurationSection, IAppConfig
    where TSubConfig : SubConfig
{
    [ConfigurationProperty("appProp1")]
    public string AppProp1
    {
        get { return (string)this["appProp1"]; }
        set { this["appProp1"] = value; }
    }

    [ConfigurationProperty("subConfig")]
    public TSubConfig SubConfig
    {
        get { return (TSubConfig)this["subConfig"]; }
        set { this["subConfig"] = value; }
    }

    // Implement the interface
    string IAppConfig.AppProp1 { get { return this.AppProp1; } }
    SubConfig IAppConfig.SubConfig { get { return this.SubConfig; } }
}
public class AppConfig : BaseAppConfig<SubConfig>
{
    const string SECTION_KEY = "AppConfig";

    public static IAppConfig Instance
    {
        get { return (IAppConfig)ConfigurationManager.GetSection(SECTION_KEY); }
    }
}

public class SubConfig : ConfigurationElement
{
    [ConfigurationProperty("supProp1")]
    public string SubProp1
    {
        get { return (string)this["supProp1"]; }
        set { this["supProp1"] = value; }
    }
}
public class ExtAppConfig : BaseAppConfig<ExtSubConfig>
{
    public static ExtAppConfig Instance
    {
        get { return (ExtAppConfig)AppConfig.Instance; }
    }

    [ConfigurationProperty("extAppProp1")]
    public string ExtAppProp1
    {
        get { return (string)this["extAppProp1"]; }
        set { this["extAppProp1"] = value; }
    }
}

public class ExtSubConfig : SubConfig
{
    [ConfigurationProperty("extSubProp1")]
    public string ExtSubProp1
    {
        get { return (string)this["extSubProp1"]; }
        set { this["extSubProp1"] = value; }
    }
}

库中有更多的定义,但它应该使扩展此配置相对容易。

并且
实例的类型不能是
ConfigurationElement
?“我不清楚你在问什么…”彼得·里奇-我已经添加了一个我正在尝试做的例子。让我知道这是否有意义。谢谢。请使用我的库。我正在创建一个网站模板,以便在我的公司分发。模板将附带一个DLL,它需要一个基本配置。我希望此模板的实现者能够扩展配置。将属性添加到基本配置很简单。棘手的是如何允许
ConfigurationSection
ConfigurationElement
s可扩展。我知道每个网站都可以创建自己的配置,但我认为按照我的方式做事会使配置更干净。但我可能错了:)