我想发布一个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; }
}
}
我想让ConfigurationSection
及其子ConfigElement
可继承。这可以使用类型参数完成,如下所示:
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; }
}
}
但是,我认为这会阻止我从我的DLL中的其他类引用静态Instance
,因为我不知道子ConfigurationElement
的最终类型。
欢迎任何关于如何更干净地实施这一点的想法或建议。
感谢。
修改
假设应用程序的配置中有<customConfigSection>
,我可以使用StandardConfiguration.GetInstance().ChildConfig.P1
访问第一个方案中的P1
值。如何在第二个场景中访问相同的值?我将如何实施GetInstance()
?
编辑2
以下是“零编码”方案:
<?xml version="1.0"?>
<configuration>
<configSections>
<section
name="customConfig"
type="WebsiteTemplate.Config.StandardConfigruation, WebsiteTemplate"
/>
</configSections>
<customConfig baseProp1="a">
<childConfig baseProp2="b" />
</customConfig>
</configuration>
以下是配置扩展的场景:
<?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>
答案 0 :(得分:2)
在第二个实例StandardConfiguration.GetInstance()
没有任何意义,因为StandardConfiguraiton
是通用的。您必须使用StandardConfiguration<MyChildConfig>.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 b = new StandardConfiguration<StandardChildConfig>();
StandardChildConfig x = StandardConfigurationBase.GetInstance().ChildConfig;
但是,我不清楚这样做的真正价值。
答案 1 :(得分:1)
我的问题的“答案”是将基本配置分解为带有类型参数和接口的抽象类。
下面显示了BaseLib.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; }
}
}
如何从BaseLib.dll访问配置
public class ArbitraryClass
{
void DoSometing()
{
Console.Write(AppConfig.Instance.SubConfig.SubProp1);
}
}
下面显示了ExtLib.dll中定义的内容。配置和子配置都已扩展。
扩展实施
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 class ExtArbitraryClass
{
void DoSometing()
{
Console.Write(ExtAppConfig.Instance.SubConfig.ExtSubProp1);
}
}
库中有一些更多的定义,但它应该使这个配置相对容易扩展。