如何在C#中改进类对象初始化?

时间:2016-05-09 05:03:23

标签: c# design-patterns

我在现有应用中使用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);

上面代码中的第二行根据应用程序需要读取的内容(临时文件夹路径,连接字符串,报告路径,电子邮件服务器设置等)更改参数。

我想做一些简单地替换这个类的东西,而不需要在调用此类的所有事件处理程序中进行太多更改。我最初计划去单身人士的路线。但是,任何更好的解决方案都会受到赞赏(甚至取代注册表的整个要求)。

2 个答案:

答案 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 +的地方。需要扩展实现事件的不同类以接收工厂对象(应该隐藏在接口后面)。