我想在C#(。Net 4.0)中创建一个winform应用程序,它使用文件对话框获取xml配置文件名。我是设计模式的新手,想在这个小应用程序中使用它。我已经阅读了很多关于各种设计模式的例子,但是无法弄清楚要使用什么。以下是此应用程序的说明。
此应用程序将运行各种作业。 XML配置文件可能包含多个作业。每个作业包含多个任务。任务可以是1)运行SQL查询2)搜索文本文件等,我计划在将来添加更多任务,如检查文件的存在。每个任务都有公共属性,如Name,Description,Enabled。每个任务还具有特定于自己的设置。例如,“运行SQL查询”任务包含XML中的连接字符串,查询和查询参数,其中“搜索文本文件”任务包含要搜索的文件和文本列表。所以我得到的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>
此应用程序还负责创建XML文件。所以我应该能够以某种方式将对象保存为XML文件格式。
我能想到的简单方法是创建一个名为Task的抽象类,其构造函数将XML作为参数。使用TaskFactory.GetInstance(XMLDocument)创建具体对象。在SQLTask和SearchTextFileTask(从Task对象派生的具体对象)的构造函数中,它反序列化包括设置的对象(每个任务类型都有自己的设置对象)。如果我想用例如数据库存储替换XML,那么这种设计的问题就是这样。我不确定我是否正在朝着正确的方向思考。如果有人可以提供包含所有必要类/接口的存根代码,我将不胜感激。
答案 0 :(得分:0)
最近,我为c#和远程Web服务器之间的数据库同步做了类似的事情。我的方法是使用XML [de]序列化和C#的Reflection命名空间从XML动态创建“未知”类。
我在下面提供了一些此代码的示例。不幸的是,我不认为这将是你所需要的,但希望它可能会给你一些想法,如果没有别的:
注意:我创建了一个名为iSyncable的接口,为可能需要同步的任何类提供了一些“基本规则” - 这也很重要,因为同步例程检查实现此接口的类作为决定发送内容的方法(例如if (typeof(iSyncable).IsAssignableFrom(type))
)。
以下迭代“Hook.MySql”类,搜索其类为“iSyncable”的任何成员,以决定是否应该序列化为XML。如果找到,则使用Reflection来动态创建成员/类的副本(dynamic cls = Activator.CreateInstance(type, Hook.MySql);
):
MemberInfo[] members = Hook.MySql.GetType().GetMembers();
foreach (MemberInfo member in members)
{
if (member.MemberType == MemberTypes.Field) {
fi = (FieldInfo)member;
type = (fi).FieldType;
if (typeof(iSyncable).IsAssignableFrom(type))
{
dynamic cls = Activator.CreateInstance(type, Hook.MySql);
MemberInfo[] members2 = type.GetMembers();
type2 = null;
foreach (MemberInfo member2 in members2)
{
if (member2.Name == "Items")
{
pi = (PropertyInfo)member2;
type2 = pi.PropertyType;
break;
}
}
if (type2 != null)
{
XML = clsXml.Serialize(fi.GetValue(Hook.MySql), cls.XMLParent, type2);
}
}
}
}
显然,这是根据我的项目量身定制的,但是有许多有用的技术应该可以转让。
这是我的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;
}
我希望这会有所帮助。如果您还有其他需要,请告诉我。