我在现有应用中使用XMLConfigManager objXMLConfig = new XMLConfigManager();
在每次触发事件时初始化。
显然,这样做没有任何意义,并且有更好的方法来建立静态类。但是同一个类读取系统注册表以找到要访问的相应数据库。下面是该类构造函数的代码。
public XMLConfigManager()
{
RegistryKey objRKConfigGroup = Registry.LocalMachine.OpenSubKey("Software\\......");
strFilePath = (string)objRKConfigGroup.GetValue("XMLFilePath");
objRKConfigGroup.Close();
string strApplicationName = (string)CacheHandler.GetCache().GetCachedElement("APPLICATION");
this.ApplicationName = strApplicationName;
}
我正在努力寻找改进方法,以便我们不会一直进入注册表。相反,我们可以刷新IIS缓存以更新注册表值(如果它发生更改(可能一年一次,如果数据库IP更改,或者发布新版本)。
现在的问题是:
静态类是一个不错的选择吗?或者我应该使用单身人士?或者我还有其他更好的选择吗?
其次,是否需要我在每个地方更改XMLConfigManager objXMLConfig = new XMLConfigManager();
行(总共约2k +事件处理程序)。
P.S。我正在考虑减少注册表访问事件应该更快的事实。我希望我的想法是正确的。此外,如果问题属于更好的堆栈交换部分,请告诉我,我会将其移动到那里。
编辑:
更多详细信息:构造函数尝试只读取一个注册表项。注册表项存储默认文件路径(在应用程序安装期间保存),以便它可以找到实际的配置文件ConfigData.xml
。
此类中的其余代码是为不同的xml元素读取ConfigData.xml
文件。一个示例函数:
public string GetConfigItem( string strConfigGroupID, string strConfigItemID, out bool bIsCacheable ) {
string strValue; //string which holds the Configuration item id
///- Get the XML Dom document which contains configuration data
XmlDocument objXmlDocument = OpenXML();
///- Get the Configuration Group Node by using XPath syntax.
XmlNode objXmlAppNode = objXmlDocument.DocumentElement.SelectSingleNode( "Nsp:Application[@Name='" + this.strAppName + "']", xmlNsp );
XmlNode objXmlConfigGroupNode = objXmlAppNode.SelectSingleNode( ".//Nsp:ConfigGroup[@ID='" + strConfigGroupID + "']", xmlNsp );
///- Get the Configuration Item Node for the specified Group by using XPath syntax.
XmlNode objXmlConfigItemNode = objXmlAppNode.SelectSingleNode( ".//Nsp:ConfigGroup[@ID='" + strConfigGroupID + "']/ConfigItem[@ID='" + strConfigItemID + "']", xmlNsp );
///- Read the value attribute from Configuration Item node.
strValue = objXmlConfigItemNode.Attributes[ "Value" ].Value;
///- get "IsCacheable" value of configuration group, whether config data can be cacheable or not.
bIsCacheable = Convert.ToBoolean( objXmlConfigGroupNode.Attributes[ "IsCacheable" ].Value );
///- Return the Configuration Item value.
return strValue;
}
其他类使用以下代码访问此类。
XMLConfigManager objConfig = new XMLConfigManager();
String prodDBConnectionString = objConfig.GetConfigItem ("ConnectionStrings", "ProductionDB", isCacheable);
上面代码中的第二行根据应用程序需要读取的内容(临时文件夹路径,连接字符串,报告路径,电子邮件服务器设置等)更改参数。
我想做一些简单地替换这个类的东西,而不需要在调用此类的所有事件处理程序中进行太多更改。我最初计划去单身人士的路线。但是,任何更好的解决方案都会受到赞赏(甚至取代注册表的整个要求)。
答案 0 :(得分:1)
根据我的理解,根据要访问的相应数据库,您创建的每个对象可能会有所不同。
我建议移动获取数据库路径的部分,创建一个静态全局字典并使用“strApplicationName”作为键,并将其作为参数传递给构造函数。
您的代码如下:
定义字典:
static Dictionary<string, XMLConfigManager> dic= new Dictionary<string, XMLConfigManager>();
获取数据库路径,并将其传递给对象:
RegistryKey objRKConfigGroup = Registry.LocalMachine.OpenSubKey("Software\\......");
strFilePath = (string)objRKConfigGroup.GetValue("XMLFilePath");
加载现有或创建新
XMLConfigManager tmp;
if(dic.ContainsKey(strFilePath)){
tmp= dic[strFilePath];
}
else{
XMLConfigManager objXMLConfig = new XMLConfigManager(strFilePath);
dic.add(objXMLConfig );
tmp = objXMLConfig;
}
答案 1 :(得分:1)
静态类是一个不错的选择吗?
静态类的缺点是它们会向您的调用类添加依赖项,这使得通过单元测试测试代码变得更加复杂。
或者我应该使用单身人士?或者我还有其他更好的选择吗?
如果考虑以下事情,单身人士可能没问题:
所以使用单身人士可能适合你的情况。我会创建一个IRegistrationCache
。后面的代码负责缓存,因此只读取一次注册表项,并将值存储在对象中。然后我会使用额外的XMLConfigManager
CTOR参数扩展IRegistrationCache
- &gt;让你的课更可测试。在这种情况下,您需要通过对singleton的附加调用来扩展2k + CTOR调用,并通过CTOR添加它。为了摆脱这种情况,我将创建一个返回IRegistrationCache
的工厂对象。此步骤隐藏了工厂类中的其他初始化逻辑 - &gt;如果你扩展你的CTOR,你只需要将它扩展到一个地方而不是2k +的地方。需要扩展实现事件的不同类以接收工厂对象(应该隐藏在接口后面)。