Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/292.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用XML构建的对象的C#设计模式_C#_Xml_Design Patterns - Fatal编程技术网

使用XML构建的对象的C#设计模式

使用XML构建的对象的C#设计模式,c#,xml,design-patterns,C#,Xml,Design Patterns,我想在C#(.NET4.0)中创建一个winform应用程序,它使用文件对话框获取xml配置文件名。我是设计模式的新手,希望在这个小应用程序中使用它。我读过很多关于各种设计模式的例子,但不知道该用什么。以下是此应用程序的说明 此应用程序将运行各种作业。XML配置文件可能包含多个作业。每个作业包含多个任务。任务可以是1)运行SQL查询2)搜索文本文件等,我计划在未来添加更多任务,如检查文件的存在。每个任务都有通用属性,如名称、描述、启用。每个任务还具有特定于其自身的设置。例如,“运行SQL查询”任

我想在C#(.NET4.0)中创建一个winform应用程序,它使用文件对话框获取xml配置文件名。我是设计模式的新手,希望在这个小应用程序中使用它。我读过很多关于各种设计模式的例子,但不知道该用什么。以下是此应用程序的说明

此应用程序将运行各种作业。XML配置文件可能包含多个作业。每个作业包含多个任务。任务可以是1)运行SQL查询2)搜索文本文件等,我计划在未来添加更多任务,如检查文件的存在。每个任务都有通用属性,如名称、描述、启用。每个任务还具有特定于其自身的设置。例如,“运行SQL查询”任务包含XML格式的connectionstring、Query和Query参数,其中“搜索文本文件”任务包含要搜索的文件和文本列表。因此,生成的XML配置文件如下所示

<root>
  <jobs>
    <job>
      <name>My first job</name>
      <description>my first job log description</description>
      <tasks>
        <task>
          <name>Get employee</name>
          <description>gets a list of all employees</description>
          <type>SQLTask</type>
          <enabled>true</enabled>
          <settings>
            <connectionstring>myconnectionstring</connectionstring>
            <query>GetAllEmployees</query>
            <params>
              <param name="Dept">HR</param>
              <param name="EmpType">Permanent</param>
            </params>
          </settings>
        </task>
        <task>
          <name>Search process log</name>
          <description>searches process log for ERROR</description>
          <type>FileSearchTask</type>
          <enabled>true</enabled>
          <settings>
            <files>
              <file>c:\process\*.log</file>
              <file>c:\event\*.log</file>
            </files>
            <searchtoken>ERROR</searchtoken>
          </settings>
        </task>
      </tasks>
    </job>
    <job>ANOTHER JOB ...
    <job>
  </jobs>
</root>

我的第一份工作
我的第一份工作日志描述
雇佣员工
获取所有员工的列表
SQLTask
真的
myconnectionstring
获取所有员工
人力资源
永久的
搜索进程日志
搜索进程日志以查找错误
文件搜索任务
真的
c:\process\*.log
c:\event\*.log
错误
另一份工作。。。
此应用程序还负责创建XML文件。因此,我应该能够以某种方式将对象保存为XML文件格式


我能想到的简单方法是创建一个名为Task的抽象类,构造函数使用XML作为参数。使用TaskFactory.GetInstance(XMLDocument)创建具体对象。在SQLTask和SearchTextFileTask(从Task对象派生的具体对象)的构造函数中,它反序列化包含设置的对象(每个任务类型都有自己的设置对象)。这种设计的问题是,如果我想用例如数据库存储来代替XML,该怎么办。我不确定我的思路是否正确。如果有人能提供一个包含所有必要类/接口的存根代码,我将不胜感激。

最近,我为c#和远程web服务器之间的数据库同步做了类似的工作。我的方法是使用XML[de]序列化和C#的反射名称空间从XML动态创建“未知”类

我在下面提供这段代码的一些示例。不幸的是,我不认为这正是你所需要的,但希望它能给你一些想法,如果没有别的:

注意:我创建了一个名为iSyncable的接口,为可能需要同步的任何类提供了一些“基本规则”——这一点也很重要,因为同步例程检查实现此接口的类,以确定发送什么(例如
if(typeof(iSyncable).IsAssignableFrom(type))

下面迭代类“Hook.MySql”,搜索类为“iSyncable”的任何成员,以决定是否应序列化为XML。如果找到,反射将用于动态创建成员/类的副本(
dynamic cls=Activator.CreateInstance(type,Hook.MySql);
):

显然,这在某种程度上是为我的项目量身定做的,但是有许多有用的技术应该可以转让

这是我的C#代码,用于将上面创建的对象序列化为XML:

public static string Serialize(dynamic o, string rootAttr, bool OmitXmlDeclaration = false, Type typeType = null)
{
    if (typeType == null) typeType = o.GetType();
    StringBuilder sb = new StringBuilder();
    XmlWriterSettings xws = new XmlWriterSettings();
    xws.OmitXmlDeclaration = OmitXmlDeclaration;
    using (XmlWriter writer = XmlWriter.Create(sb, xws))
    {
        try
        {
            new XmlSerializer(o.GetType(), null, new Type[] { typeType }, new XmlRootAttribute(rootAttr), "").Serialize(writer, o);
            //new XmlSerializer(o.GetType(), new XmlRootAttribute(rootAttr)).Serialize(writer, o);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.InnerException);
            Console.WriteLine(e.StackTrace);
        }
    }
    return fstr;
}

我希望这能有所帮助。如果您还需要什么,请告诉我。

您可以使用Linq to XML获取任务名称和XML的相关部分,然后还可以使用它从XML创建对象。或者将其序列化回XML。当然,如果对象是可序列化的,您可以在返回时将其序列化为XML,而不是使用Linq。我可以反序列化/序列化,但我不想依赖XML,特别是XML的“设置”部分。
public static string Serialize(dynamic o, string rootAttr, bool OmitXmlDeclaration = false, Type typeType = null)
{
    if (typeType == null) typeType = o.GetType();
    StringBuilder sb = new StringBuilder();
    XmlWriterSettings xws = new XmlWriterSettings();
    xws.OmitXmlDeclaration = OmitXmlDeclaration;
    using (XmlWriter writer = XmlWriter.Create(sb, xws))
    {
        try
        {
            new XmlSerializer(o.GetType(), null, new Type[] { typeType }, new XmlRootAttribute(rootAttr), "").Serialize(writer, o);
            //new XmlSerializer(o.GetType(), new XmlRootAttribute(rootAttr)).Serialize(writer, o);
        }
        catch (Exception e)
        {
            Console.WriteLine(e.Message);
            Console.WriteLine(e.InnerException);
            Console.WriteLine(e.StackTrace);
        }
    }
    return fstr;
}