Jon*_*ski 25 .net c# configuration .net-3.5
我有一个像这样的Config类:
public class MyConfig : ConfigurationSection
{
[ConfigurationProperty("MyProperty", IsRequired = true)]
public string MyProperty
{
get { return (string)this["MyProperty"]; }
set { this["MyProperty"] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
它正在由另一个类实例化
(MyConfig)ConfigurationManager.GetSection("myConfig")
Run Code Online (Sandbox Code Playgroud)
我们正在进行一些更改,现在将配置文件作为xml存储在数据库中,就像它当前在配置文件中一样.
我想将MyConfig维护为ConfigurationSection以实现向后兼容,但仍然可以使用从DB检索的XML字符串来实例化它.
可能吗?如果是这样,怎么样?(请记住它应该仍然可以像上面的实例一样工作)
Sim*_*ier 14
以下是我通常的做法:只需将这些成员添加到MyConfig类:
public class MyConfig : ConfigurationSection
{
private static MyConfig _current;
public static MyConfig Current
{
get
{
if (_current == null)
{
switch(ConfigurationStorageType) // where do you want read config from?
{
case ConfigFile: // from .config file
_current = ConfigurationManager.GetSection("MySectionName") as MyConfig;
break;
case ConfigDb: // from database
default:
using (Stream stream = GetMyStreamFromDb())
{
using (XmlTextReader reader = new XmlTextReader(stream))
{
_current = Get(reader);
}
}
break;
}
}
return _current;
}
}
public static MyConfig Get(XmlReader reader)
{
if (reader == null)
throw new ArgumentNullException("reader");
MyConfig section = new MyConfig();
section.DeserializeSection(reader);
return section;
}
}
Run Code Online (Sandbox Code Playgroud)
这样,您在MyConfig类中无需更改,但您仍需要使用此类代码更改客户访问它的方式:
string myProp = MyConfig.Current.MyProperty;
Run Code Online (Sandbox Code Playgroud)
如果需要将任何System.Configuration.ConfigurationSection存储在数据库中,您可以考虑编写通用的部分阅读器,如下所示:
public class ConfigurationSectionReader where T : ConfigurationSection, new()
{
public T GetSection( string sectionXml )
{
T section = new T();
using ( StringReader stringReader = new StringReader( sectionXml ) )
using ( XmlReader reader = XmlReader.Create( stringReader, new XmlReaderSettings() { CloseInput = true } ) )
{
reader.Read();
section.GetType().GetMethod( "DeserializeElement", BindingFlags.NonPublic | BindingFlags.Instance ).Invoke( section, new object[] { reader, true } );
}
return section;
}
}
这适用于覆盖DeserializeElement方法的所有类.例如
protected override void DeserializeElement( XmlReader reader, bool serializeCollectionKey )
{
XmlDocument document = new XmlDocument();
document.LoadXml( reader.ReadOuterXml() );
MyProperty = document.DocumentElement.HasAttribute( "MyProperty" )
? document.DocumentElement.Attributes[ "MyProperty" ].Value
: string.Empty;
}
你可以得到这样一个部分:
var reader = new ConfigurationSectionReader();
var section = reader.GetSection( sectionXml ); // where sectionXml is the XML string retrieved from the DB
我的建议是保留当前的 MyConfig 类,但在构造函数中从数据库加载 XML,然后在 MyConfig 的每个属性中,您可以输入逻辑来确定从何处获取值(数据库或 .config 文件)如果您需要从任一位置提取配置,或者如果该值为空则将其回退。
public class MyConfig : ConfigurationSection
{
public MyConfig()
{
// throw some code in here to retrieve your XML from your database
// deserialize your XML and store it
_myProperty = "<deserialized value from db>";
}
private string _myProperty = string.Empty;
[ConfigurationProperty("MyProperty", IsRequired = true)]
public string MyProperty
{
get
{
if (_myProperty != null && _myProperty.Length > 0)
return _myProperty;
else
return (string)this["MyProperty"];
}
set { this["MyProperty"] = value; }
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10868 次 |
| 最近记录: |