当前位置:
首页 > 编程开发 > Objective-C编程 >
-
反射学习系列3 反射实例应用
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。
1、使用反射通过读取配置文件来动态的创建相关类的对象
我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况
结构图:
接口
interface ILog
{
bool Write(string message);
bool Write(Exception ex);
}
TextFileLog
class TextFileLog : ILog
{
public bool Write(string message)
{
string fileDir = ConfigurationManager.AppSettings["LogTarget"].ToString();
using (StreamWriter w = File.AppendText(fileDir))
{
// w.Write(" Log Entry : ");
w.WriteLine("发生时间{0}", DateTime.Now.ToLocalTime().ToString());
w.WriteLine("日志内容为:{0}", message);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
w.Close();
}
return true;
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogType" value="LogClassLibrary.TextFileLog"/>
<!--
本程序集配置
<add key="LogType" value="ConsoleApplication2.Log例子.TextFileLog"/>
-->
<!-- XmlFileLog TextFileLog-->
<add key="LogTarget" value="c:log.txt"/>
</appSettings>
</configuration>
主程序
public static void Main()
{
#region 同程序集下
System.Type type = System.Type.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
ILog log = (ILog)Activator.CreateInstance(type);
log.Write(new Exception("异常测试"));
#endregion
}
如果在不同的程序集下,那主函数和配置会略有不同
不同程序集主函数
public static void Main()
{
#region 不同程序集
string assemblyPath = Path.Combine(Environment.CurrentDirectory, "LogClassLibrary.dll");
Assembly a = Assembly.LoadFrom(assemblyPath);
Type type = a.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
LogClassLibrary.ILog log = (LogClassLibrary.ILog)type.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);
log.Write(new Exception("异常测试"));
#endregion
}
2、插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出,通过反射可以非常方便的动态加载程序集。因此,利用反射的动态加载代码能力,可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
这里只是选贴一部分代码,详细分析请看源码
结构图
接口部分
publicinterfaceIHost
{
List<ILog>Plugins{get;}
intLoadPlugins(stringpath);
ILogGetLog(stringname);
}
publicinterfaceILog
{
boolWrite(stringmessage);
boolWrite(Exceptionex);
}
宿主实现
publicclassHost:IHost
{
privateList<ILog>plugins=newList<ILog>();
#regionIHost成员
publicList<ILog>Plugins
{
get{returnplugins;}
}
publicintLoadPlugins(stringpath)
{
string[]assemblyFiles=Directory.GetFiles(path,"*.dll");
foreach(varfileinassemblyFiles)
{
Assemblyassembly=Assembly.LoadFrom(file);
foreach(vartypeinassembly.GetExportedTypes())
{
if(type.IsClass&&typeof(ILog).IsAssignableFrom(type))
{
ILogplugin=Activator.CreateInstance(type)asILog;
plugins.Add(plugin);
}
}
}
returnplugins.Count;
}
publicILogGetLog(stringname)
{
foreach(variteminplugins)
{
if(item.GetType().ToString()==name)
{
returnitem;
}
}
returnnull;
}
#endregion
}
ILog的实现和上例基本一样,请参考
主程序代码
staticvoidMain(string[]args)
{
Host.Hosthost=newHost.Host();
host.LoadPlugins(".");
InterfaceLayer.ILoglog=host.GetLog(ConfigurationManager.AppSettings["LogType"].ToString());
log.Write(newException("异常测试"));
}
3、分析对象,得到对象中的属性值
大家使用应都用过asp.net中的DropdownList,在绑定其值的时候绝大多数情况下我们做的都是同样的事情,获得数据源,根据数据源中的某些列绑定控件,下边我们来说说通用情况的处理方式。我们只需要提供数据集合,以及需要绑定到控件的两个属性(text,value)名即可。
publicclassDDlControl
{
privateListControlunderlyingList;
publicDDlControl(ListControlunderlyingList)
{
this.underlyingList=underlyingList;
}
publicvoidAdd(IDDLddl)
{
underlyingList.Items.Add(newListItem(ddl.Name,ddl.Value));
}
publicvoidAdd<T>(Tt,stringnameStr,stringvalueStr)
{
stringname=Convert.ToString(t.GetType().InvokeMember
(nameStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
stringvalue=Convert.ToString(t.GetType().InvokeMember
(valueStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
Add(newDDLStruct(name,value));
}
publicvoidClear()
{
underlyingList.Items.Clear();
}
publicIDDLSelectedItem
{
get
{
ListItemitem=underlyingList.SelectedItem;
returnnewDDLStruct(item.Text,item.Value);
}
}
publicvoidBindTo<T>(IEnumerable<T>list,stringnameStr,stringvalueStr)
{
Clear();
foreach(variteminlist)
{
Add<T>(item,nameStr,valueStr);
}
}
publicstringSelectValue
{
get
{
returnunderlyingList.SelectedValue;
}
set
{
underlyingList.SelectedValue=value;
}
}
}
publicstructDDLStruct
{
publicDDLStruct(stringname,stringvalue)
{
this.name=name;
this.value=value;
}
privatestringname;
privatestringvalue;
publicstringName
{
get{returnname;}
}
publicstringValue
{
get{returnvalue;}
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。
1、使用反射通过读取配置文件来动态的创建相关类的对象
我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况
结构图:
接口
interface ILog
{
bool Write(string message);
bool Write(Exception ex);
}
TextFileLog
class TextFileLog : ILog
{
public bool Write(string message)
{
string fileDir = ConfigurationManager.AppSettings["LogTarget"].ToString();
using (StreamWriter w = File.AppendText(fileDir))
{
// w.Write(" Log Entry : ");
w.WriteLine("发生时间{0}", DateTime.Now.ToLocalTime().ToString());
w.WriteLine("日志内容为:{0}", message);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
w.Close();
}
return true;
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogType" value="LogClassLibrary.TextFileLog"/>
<!--
本程序集配置
<add key="LogType" value="ConsoleApplication2.Log例子.TextFileLog"/>
-->
<!-- XmlFileLog TextFileLog-->
<add key="LogTarget" value="c:log.txt"/>
</appSettings>
</configuration>
主程序
public static void Main()
{
#region 同程序集下
System.Type type = System.Type.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
ILog log = (ILog)Activator.CreateInstance(type);
log.Write(new Exception("异常测试"));
#endregion
}
如果在不同的程序集下,那主函数和配置会略有不同
不同程序集主函数
public static void Main()
{
#region 不同程序集
string assemblyPath = Path.Combine(Environment.CurrentDirectory, "LogClassLibrary.dll");
Assembly a = Assembly.LoadFrom(assemblyPath);
Type type = a.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
LogClassLibrary.ILog log = (LogClassLibrary.ILog)type.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);
log.Write(new Exception("异常测试"));
#endregion
}
2、插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出,通过反射可以非常方便的动态加载程序集。因此,利用反射的动态加载代码能力,可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
这里只是选贴一部分代码,详细分析请看源码
结构图
接口部分
publicinterfaceIHost
{
List<ILog>Plugins{get;}
intLoadPlugins(stringpath);
ILogGetLog(stringname);
}
publicinterfaceILog
{
boolWrite(stringmessage);
boolWrite(Exceptionex);
}
宿主实现
publicclassHost:IHost
{
privateList<ILog>plugins=newList<ILog>();
#regionIHost成员
publicList<ILog>Plugins
{
get{returnplugins;}
}
publicintLoadPlugins(stringpath)
{
string[]assemblyFiles=Directory.GetFiles(path,"*.dll");
foreach(varfileinassemblyFiles)
{
Assemblyassembly=Assembly.LoadFrom(file);
foreach(vartypeinassembly.GetExportedTypes())
{
if(type.IsClass&&typeof(ILog).IsAssignableFrom(type))
{
ILogplugin=Activator.CreateInstance(type)asILog;
plugins.Add(plugin);
}
}
}
returnplugins.Count;
}
publicILogGetLog(stringname)
{
foreach(variteminplugins)
{
if(item.GetType().ToString()==name)
{
returnitem;
}
}
returnnull;
}
#endregion
}
ILog的实现和上例基本一样,请参考
主程序代码
staticvoidMain(string[]args)
{
Host.Hosthost=newHost.Host();
host.LoadPlugins(".");
InterfaceLayer.ILoglog=host.GetLog(ConfigurationManager.AppSettings["LogType"].ToString());
log.Write(newException("异常测试"));
}
3、分析对象,得到对象中的属性值
大家使用应都用过asp.net中的DropdownList,在绑定其值的时候绝大多数情况下我们做的都是同样的事情,获得数据源,根据数据源中的某些列绑定控件,下边我们来说说通用情况的处理方式。我们只需要提供数据集合,以及需要绑定到控件的两个属性(text,value)名即可。
publicclassDDlControl
{
privateListControlunderlyingList;
publicDDlControl(ListControlunderlyingList)
{
this.underlyingList=underlyingList;
}
publicvoidAdd(IDDLddl)
{
underlyingList.Items.Add(newListItem(ddl.Name,ddl.Value));
}
publicvoidAdd<T>(Tt,stringnameStr,stringvalueStr)
{
stringname=Convert.ToString(t.GetType().InvokeMember
(nameStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
stringvalue=Convert.ToString(t.GetType().InvokeMember
(valueStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
Add(newDDLStruct(name,value));
}
publicvoidClear()
{
underlyingList.Items.Clear();
}
publicIDDLSelectedItem
{
get
{
ListItemitem=underlyingList.SelectedItem;
returnnewDDLStruct(item.Text,item.Value);
}
}
publicvoidBindTo<T>(IEnumerable<T>list,stringnameStr,stringvalueStr)
{
Clear();
foreach(variteminlist)
{
Add<T>(item,nameStr,valueStr);
}
}
publicstringSelectValue
{
get
{
returnunderlyingList.SelectedValue;
}
set
{
underlyingList.SelectedValue=value;
}
}
}
publicstructDDLStruct
{
publicDDLStruct(stringname,stringvalue)
{
this.name=name;
this.value=value;
}
privatestringname;
privatestringvalue;
publicstringName
{
get{returnname;}
}
publicstringValue
{
get{returnvalue;}
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。
1、使用反射通过读取配置文件来动态的创建相关类的对象
我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况
结构图:
接口
interface ILog
{
bool Write(string message);
bool Write(Exception ex);
}
TextFileLog
class TextFileLog : ILog
{
public bool Write(string message)
{
string fileDir = ConfigurationManager.AppSettings["LogTarget"].ToString();
using (StreamWriter w = File.AppendText(fileDir))
{
// w.Write(" Log Entry : ");
w.WriteLine("发生时间{0}", DateTime.Now.ToLocalTime().ToString());
w.WriteLine("日志内容为:{0}", message);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
w.Close();
}
return true;
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogType" value="LogClassLibrary.TextFileLog"/>
<!--
本程序集配置
<add key="LogType" value="ConsoleApplication2.Log例子.TextFileLog"/>
-->
<!-- XmlFileLog TextFileLog-->
<add key="LogTarget" value="c:log.txt"/>
</appSettings>
</configuration>
主程序
public static void Main()
{
#region 同程序集下
System.Type type = System.Type.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
ILog log = (ILog)Activator.CreateInstance(type);
log.Write(new Exception("异常测试"));
#endregion
}
如果在不同的程序集下,那主函数和配置会略有不同
不同程序集主函数
public static void Main()
{
#region 不同程序集
string assemblyPath = Path.Combine(Environment.CurrentDirectory, "LogClassLibrary.dll");
Assembly a = Assembly.LoadFrom(assemblyPath);
Type type = a.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
LogClassLibrary.ILog log = (LogClassLibrary.ILog)type.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);
log.Write(new Exception("异常测试"));
#endregion
}
2、插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出,通过反射可以非常方便的动态加载程序集。因此,利用反射的动态加载代码能力,可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
这里只是选贴一部分代码,详细分析请看源码
结构图
接口部分
publicinterfaceIHost
{
List<ILog>Plugins{get;}
intLoadPlugins(stringpath);
ILogGetLog(stringname);
}
publicinterfaceILog
{
boolWrite(stringmessage);
boolWrite(Exceptionex);
}
宿主实现
publicclassHost:IHost
{
privateList<ILog>plugins=newList<ILog>();
#regionIHost成员
publicList<ILog>Plugins
{
get{returnplugins;}
}
publicintLoadPlugins(stringpath)
{
string[]assemblyFiles=Directory.GetFiles(path,"*.dll");
foreach(varfileinassemblyFiles)
{
Assemblyassembly=Assembly.LoadFrom(file);
foreach(vartypeinassembly.GetExportedTypes())
{
if(type.IsClass&&typeof(ILog).IsAssignableFrom(type))
{
ILogplugin=Activator.CreateInstance(type)asILog;
plugins.Add(plugin);
}
}
}
returnplugins.Count;
}
publicILogGetLog(stringname)
{
foreach(variteminplugins)
{
if(item.GetType().ToString()==name)
{
returnitem;
}
}
returnnull;
}
#endregion
}
ILog的实现和上例基本一样,请参考
主程序代码
staticvoidMain(string[]args)
{
Host.Hosthost=newHost.Host();
host.LoadPlugins(".");
InterfaceLayer.ILoglog=host.GetLog(ConfigurationManager.AppSettings["LogType"].ToString());
log.Write(newException("异常测试"));
}
3、分析对象,得到对象中的属性值
大家使用应都用过asp.net中的DropdownList,在绑定其值的时候绝大多数情况下我们做的都是同样的事情,获得数据源,根据数据源中的某些列绑定控件,下边我们来说说通用情况的处理方式。我们只需要提供数据集合,以及需要绑定到控件的两个属性(text,value)名即可。
publicclassDDlControl
{
privateListControlunderlyingList;
publicDDlControl(ListControlunderlyingList)
{
this.underlyingList=underlyingList;
}
publicvoidAdd(IDDLddl)
{
underlyingList.Items.Add(newListItem(ddl.Name,ddl.Value));
}
publicvoidAdd<T>(Tt,stringnameStr,stringvalueStr)
{
stringname=Convert.ToString(t.GetType().InvokeMember
(nameStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
stringvalue=Convert.ToString(t.GetType().InvokeMember
(valueStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
Add(newDDLStruct(name,value));
}
publicvoidClear()
{
underlyingList.Items.Clear();
}
publicIDDLSelectedItem
{
get
{
ListItemitem=underlyingList.SelectedItem;
returnnewDDLStruct(item.Text,item.Value);
}
}
publicvoidBindTo<T>(IEnumerable<T>list,stringnameStr,stringvalueStr)
{
Clear();
foreach(variteminlist)
{
Add<T>(item,nameStr,valueStr);
}
}
publicstringSelectValue
{
get
{
returnunderlyingList.SelectedValue;
}
set
{
underlyingList.SelectedValue=value;
}
}
}
publicstructDDLStruct
{
publicDDLStruct(stringname,stringvalue)
{
this.name=name;
this.value=value;
}
privatestringname;
privatestringvalue;
publicstringName
{
get{returnname;}
}
publicstringValue
{
get{returnvalue;}
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。
1、使用反射通过读取配置文件来动态的创建相关类的对象
我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况
结构图:
接口
interface ILog
{
bool Write(string message);
bool Write(Exception ex);
}
TextFileLog
class TextFileLog : ILog
{
public bool Write(string message)
{
string fileDir = ConfigurationManager.AppSettings["LogTarget"].ToString();
using (StreamWriter w = File.AppendText(fileDir))
{
// w.Write(" Log Entry : ");
w.WriteLine("发生时间{0}", DateTime.Now.ToLocalTime().ToString());
w.WriteLine("日志内容为:{0}", message);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
w.Close();
}
return true;
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogType" value="LogClassLibrary.TextFileLog"/>
<!--
本程序集配置
<add key="LogType" value="ConsoleApplication2.Log例子.TextFileLog"/>
-->
<!-- XmlFileLog TextFileLog-->
<add key="LogTarget" value="c:log.txt"/>
</appSettings>
</configuration>
主程序
public static void Main()
{
#region 同程序集下
System.Type type = System.Type.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
ILog log = (ILog)Activator.CreateInstance(type);
log.Write(new Exception("异常测试"));
#endregion
}
如果在不同的程序集下,那主函数和配置会略有不同
不同程序集主函数
public static void Main()
{
#region 不同程序集
string assemblyPath = Path.Combine(Environment.CurrentDirectory, "LogClassLibrary.dll");
Assembly a = Assembly.LoadFrom(assemblyPath);
Type type = a.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
LogClassLibrary.ILog log = (LogClassLibrary.ILog)type.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);
log.Write(new Exception("异常测试"));
#endregion
}
2、插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出,通过反射可以非常方便的动态加载程序集。因此,利用反射的动态加载代码能力,可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
这里只是选贴一部分代码,详细分析请看源码
结构图
接口部分
publicinterfaceIHost
{
List<ILog>Plugins{get;}
intLoadPlugins(stringpath);
ILogGetLog(stringname);
}
publicinterfaceILog
{
boolWrite(stringmessage);
boolWrite(Exceptionex);
}
宿主实现
publicclassHost:IHost
{
privateList<ILog>plugins=newList<ILog>();
#regionIHost成员
publicList<ILog>Plugins
{
get{returnplugins;}
}
publicintLoadPlugins(stringpath)
{
string[]assemblyFiles=Directory.GetFiles(path,"*.dll");
foreach(varfileinassemblyFiles)
{
Assemblyassembly=Assembly.LoadFrom(file);
foreach(vartypeinassembly.GetExportedTypes())
{
if(type.IsClass&&typeof(ILog).IsAssignableFrom(type))
{
ILogplugin=Activator.CreateInstance(type)asILog;
plugins.Add(plugin);
}
}
}
returnplugins.Count;
}
publicILogGetLog(stringname)
{
foreach(variteminplugins)
{
if(item.GetType().ToString()==name)
{
returnitem;
}
}
returnnull;
}
#endregion
}
ILog的实现和上例基本一样,请参考
主程序代码
staticvoidMain(string[]args)
{
Host.Hosthost=newHost.Host();
host.LoadPlugins(".");
InterfaceLayer.ILoglog=host.GetLog(ConfigurationManager.AppSettings["LogType"].ToString());
log.Write(newException("异常测试"));
}
3、分析对象,得到对象中的属性值
大家使用应都用过asp.net中的DropdownList,在绑定其值的时候绝大多数情况下我们做的都是同样的事情,获得数据源,根据数据源中的某些列绑定控件,下边我们来说说通用情况的处理方式。我们只需要提供数据集合,以及需要绑定到控件的两个属性(text,value)名即可。
publicclassDDlControl
{
privateListControlunderlyingList;
publicDDlControl(ListControlunderlyingList)
{
this.underlyingList=underlyingList;
}
publicvoidAdd(IDDLddl)
{
underlyingList.Items.Add(newListItem(ddl.Name,ddl.Value));
}
publicvoidAdd<T>(Tt,stringnameStr,stringvalueStr)
{
stringname=Convert.ToString(t.GetType().InvokeMember
(nameStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
stringvalue=Convert.ToString(t.GetType().InvokeMember
(valueStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
Add(newDDLStruct(name,value));
}
publicvoidClear()
{
underlyingList.Items.Clear();
}
publicIDDLSelectedItem
{
get
{
ListItemitem=underlyingList.SelectedItem;
returnnewDDLStruct(item.Text,item.Value);
}
}
publicvoidBindTo<T>(IEnumerable<T>list,stringnameStr,stringvalueStr)
{
Clear();
foreach(variteminlist)
{
Add<T>(item,nameStr,valueStr);
}
}
publicstringSelectValue
{
get
{
returnunderlyingList.SelectedValue;
}
set
{
underlyingList.SelectedValue=value;
}
}
}
publicstructDDLStruct
{
publicDDLStruct(stringname,stringvalue)
{
this.name=name;
this.value=value;
}
privatestringname;
privatestringvalue;
publicstringName
{
get{returnname;}
}
publicstringValue
{
get{returnvalue;}
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。
1、使用反射通过读取配置文件来动态的创建相关类的对象
我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况
结构图:
接口
interface ILog
{
bool Write(string message);
bool Write(Exception ex);
}
TextFileLog
class TextFileLog : ILog
{
public bool Write(string message)
{
string fileDir = ConfigurationManager.AppSettings["LogTarget"].ToString();
using (StreamWriter w = File.AppendText(fileDir))
{
// w.Write(" Log Entry : ");
w.WriteLine("发生时间{0}", DateTime.Now.ToLocalTime().ToString());
w.WriteLine("日志内容为:{0}", message);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
w.Close();
}
return true;
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogType" value="LogClassLibrary.TextFileLog"/>
<!--
本程序集配置
<add key="LogType" value="ConsoleApplication2.Log例子.TextFileLog"/>
-->
<!-- XmlFileLog TextFileLog-->
<add key="LogTarget" value="c:log.txt"/>
</appSettings>
</configuration>
主程序
public static void Main()
{
#region 同程序集下
System.Type type = System.Type.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
ILog log = (ILog)Activator.CreateInstance(type);
log.Write(new Exception("异常测试"));
#endregion
}
如果在不同的程序集下,那主函数和配置会略有不同
不同程序集主函数
public static void Main()
{
#region 不同程序集
string assemblyPath = Path.Combine(Environment.CurrentDirectory, "LogClassLibrary.dll");
Assembly a = Assembly.LoadFrom(assemblyPath);
Type type = a.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
LogClassLibrary.ILog log = (LogClassLibrary.ILog)type.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);
log.Write(new Exception("异常测试"));
#endregion
}
2、插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出,通过反射可以非常方便的动态加载程序集。因此,利用反射的动态加载代码能力,可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
这里只是选贴一部分代码,详细分析请看源码
结构图
接口部分
publicinterfaceIHost
{
List<ILog>Plugins{get;}
intLoadPlugins(stringpath);
ILogGetLog(stringname);
}
publicinterfaceILog
{
boolWrite(stringmessage);
boolWrite(Exceptionex);
}
宿主实现
publicclassHost:IHost
{
privateList<ILog>plugins=newList<ILog>();
#regionIHost成员
publicList<ILog>Plugins
{
get{returnplugins;}
}
publicintLoadPlugins(stringpath)
{
string[]assemblyFiles=Directory.GetFiles(path,"*.dll");
foreach(varfileinassemblyFiles)
{
Assemblyassembly=Assembly.LoadFrom(file);
foreach(vartypeinassembly.GetExportedTypes())
{
if(type.IsClass&&typeof(ILog).IsAssignableFrom(type))
{
ILogplugin=Activator.CreateInstance(type)asILog;
plugins.Add(plugin);
}
}
}
returnplugins.Count;
}
publicILogGetLog(stringname)
{
foreach(variteminplugins)
{
if(item.GetType().ToString()==name)
{
returnitem;
}
}
returnnull;
}
#endregion
}
ILog的实现和上例基本一样,请参考
主程序代码
staticvoidMain(string[]args)
{
Host.Hosthost=newHost.Host();
host.LoadPlugins(".");
InterfaceLayer.ILoglog=host.GetLog(ConfigurationManager.AppSettings["LogType"].ToString());
log.Write(newException("异常测试"));
}
3、分析对象,得到对象中的属性值
大家使用应都用过asp.net中的DropdownList,在绑定其值的时候绝大多数情况下我们做的都是同样的事情,获得数据源,根据数据源中的某些列绑定控件,下边我们来说说通用情况的处理方式。我们只需要提供数据集合,以及需要绑定到控件的两个属性(text,value)名即可。
publicclassDDlControl
{
privateListControlunderlyingList;
publicDDlControl(ListControlunderlyingList)
{
this.underlyingList=underlyingList;
}
publicvoidAdd(IDDLddl)
{
underlyingList.Items.Add(newListItem(ddl.Name,ddl.Value));
}
publicvoidAdd<T>(Tt,stringnameStr,stringvalueStr)
{
stringname=Convert.ToString(t.GetType().InvokeMember
(nameStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
stringvalue=Convert.ToString(t.GetType().InvokeMember
(valueStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
Add(newDDLStruct(name,value));
}
publicvoidClear()
{
underlyingList.Items.Clear();
}
publicIDDLSelectedItem
{
get
{
ListItemitem=underlyingList.SelectedItem;
returnnewDDLStruct(item.Text,item.Value);
}
}
publicvoidBindTo<T>(IEnumerable<T>list,stringnameStr,stringvalueStr)
{
Clear();
foreach(variteminlist)
{
Add<T>(item,nameStr,valueStr);
}
}
publicstringSelectValue
{
get
{
returnunderlyingList.SelectedValue;
}
set
{
underlyingList.SelectedValue=value;
}
}
}
publicstructDDLStruct
{
publicDDLStruct(stringname,stringvalue)
{
this.name=name;
this.value=value;
}
privatestringname;
privatestringvalue;
publicstringName
{
get{returnname;}
}
publicstringValue
{
get{returnvalue;}
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
制作者:剑锋冷月 单位:无忧统计网,www.51stat.net
例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。
1、使用反射通过读取配置文件来动态的创建相关类的对象
我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况
结构图:
接口
interface ILog
{
bool Write(string message);
bool Write(Exception ex);
}
TextFileLog
class TextFileLog : ILog
{
public bool Write(string message)
{
string fileDir = ConfigurationManager.AppSettings["LogTarget"].ToString();
using (StreamWriter w = File.AppendText(fileDir))
{
// w.Write(" Log Entry : ");
w.WriteLine("发生时间{0}", DateTime.Now.ToLocalTime().ToString());
w.WriteLine("日志内容为:{0}", message);
w.WriteLine("-------------------------------");
// Update the underlying file.
w.Flush();
w.Close();
}
return true;
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
App.config配置
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<appSettings>
<add key="LogType" value="LogClassLibrary.TextFileLog"/>
<!--
本程序集配置
<add key="LogType" value="ConsoleApplication2.Log例子.TextFileLog"/>
-->
<!-- XmlFileLog TextFileLog-->
<add key="LogTarget" value="c:log.txt"/>
</appSettings>
</configuration>
主程序
public static void Main()
{
#region 同程序集下
System.Type type = System.Type.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
ILog log = (ILog)Activator.CreateInstance(type);
log.Write(new Exception("异常测试"));
#endregion
}
如果在不同的程序集下,那主函数和配置会略有不同
不同程序集主函数
public static void Main()
{
#region 不同程序集
string assemblyPath = Path.Combine(Environment.CurrentDirectory, "LogClassLibrary.dll");
Assembly a = Assembly.LoadFrom(assemblyPath);
Type type = a.GetType(ConfigurationManager.AppSettings["LogType"].ToString());
LogClassLibrary.ILog log = (LogClassLibrary.ILog)type.InvokeMember(null,BindingFlags.CreateInstance,null,null,null);
log.Write(new Exception("异常测试"));
#endregion
}
2、插件编程技术
插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出,通过反射可以非常方便的动态加载程序集。因此,利用反射的动态加载代码能力,可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能,实现插件功能的所有类都必须实现定义插件的接口。
这里只是选贴一部分代码,详细分析请看源码
结构图
接口部分
publicinterfaceIHost
{
List<ILog>Plugins{get;}
intLoadPlugins(stringpath);
ILogGetLog(stringname);
}
publicinterfaceILog
{
boolWrite(stringmessage);
boolWrite(Exceptionex);
}
宿主实现
publicclassHost:IHost
{
privateList<ILog>plugins=newList<ILog>();
#regionIHost成员
publicList<ILog>Plugins
{
get{returnplugins;}
}
publicintLoadPlugins(stringpath)
{
string[]assemblyFiles=Directory.GetFiles(path,"*.dll");
foreach(varfileinassemblyFiles)
{
Assemblyassembly=Assembly.LoadFrom(file);
foreach(vartypeinassembly.GetExportedTypes())
{
if(type.IsClass&&typeof(ILog).IsAssignableFrom(type))
{
ILogplugin=Activator.CreateInstance(type)asILog;
plugins.Add(plugin);
}
}
}
returnplugins.Count;
}
publicILogGetLog(stringname)
{
foreach(variteminplugins)
{
if(item.GetType().ToString()==name)
{
returnitem;
}
}
returnnull;
}
#endregion
}
ILog的实现和上例基本一样,请参考
主程序代码
staticvoidMain(string[]args)
{
Host.Hosthost=newHost.Host();
host.LoadPlugins(".");
InterfaceLayer.ILoglog=host.GetLog(ConfigurationManager.AppSettings["LogType"].ToString());
log.Write(newException("异常测试"));
}
3、分析对象,得到对象中的属性值
大家使用应都用过asp.net中的DropdownList,在绑定其值的时候绝大多数情况下我们做的都是同样的事情,获得数据源,根据数据源中的某些列绑定控件,下边我们来说说通用情况的处理方式。我们只需要提供数据集合,以及需要绑定到控件的两个属性(text,value)名即可。
publicclassDDlControl
{
privateListControlunderlyingList;
publicDDlControl(ListControlunderlyingList)
{
this.underlyingList=underlyingList;
}
publicvoidAdd(IDDLddl)
{
underlyingList.Items.Add(newListItem(ddl.Name,ddl.Value));
}
publicvoidAdd<T>(Tt,stringnameStr,stringvalueStr)
{
stringname=Convert.ToString(t.GetType().InvokeMember
(nameStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
stringvalue=Convert.ToString(t.GetType().InvokeMember
(valueStr,System.Reflection.BindingFlags.GetProperty,null,t,null));
Add(newDDLStruct(name,value));
}
publicvoidClear()
{
underlyingList.Items.Clear();
}
publicIDDLSelectedItem
{
get
{
ListItemitem=underlyingList.SelectedItem;
returnnewDDLStruct(item.Text,item.Value);
}
}
publicvoidBindTo<T>(IEnumerable<T>list,stringnameStr,stringvalueStr)
{
Clear();
foreach(variteminlist)
{
Add<T>(item,nameStr,valueStr);
}
}
publicstringSelectValue
{
get
{
returnunderlyingList.SelectedValue;
}
set
{
underlyingList.SelectedValue=value;
}
}
}
publicstructDDLStruct
{
publicDDLStruct(stringname,stringvalue)
{
this.name=name;
this.value=value;
}
privatestringname;
privatestringvalue;
publicstringName
{
get{returnname;}
}
publicstringValue
{
get{returnvalue;}
}
}
XmlFileLog
class XmlFileLog : ILog
{
public bool Write(string message)
{
string xmlFilePath = ConfigurationManager.AppSettings["LogTarget"].ToString();
if (File.Exists(xmlFilePath))
{
XmlDocument doc = new XmlDocument();
doc.Load(xmlFilePath);
XmlDocumentFragment docFrag = doc.CreateDocumentFragment();
XmlNode nod = doc.SelectSingleNode("Logs");
docFrag.InnerXml = "<Log><Time>" + DateTime.Now.ToLocalTime().ToString()
+ "</Time><Message>" + message + "</Message></Log>";
nod.AppendChild(docFrag);
doc.Save(xmlFilePath);
return true;
}
else
{
XmlWriterSettings settings = new XmlWriterSettings();
settings.Indent = true; //设置缩进
settings.ConformanceLevel = ConformanceLevel.Auto;
settings.IndentChars = " ";
settings.OmitXmlDeclaration = false;
using (XmlWriter writer = XmlWriter.Create(xmlFilePath, settings))
{
//Start writing the XML document
writer.WriteStartDocument(false);
//Start with the root element
writer.WriteStartElement("Logs");
writer.WriteStartElement("Log");
writer.WriteStartElement("Time");
writer.WriteString(DateTime.Now.ToLocalTime().ToString());
writer.WriteEndElement();
writer.WriteStartElement("Message");
writer.WriteString(message);
writer.WriteEndElement();
writer.WriteEndElement();
writer.WriteEndDocument();
//Flush the object and write the XML data to the file
writer.Flush();
return true;
}
}
}
public bool Write(Exception ex)
{
Write(ex.Message);
return true;
}
}
最新更新
nodejs爬虫
Python正则表达式完全指南
爬取豆瓣Top250图书数据
shp 地图文件批量添加字段
爬虫小试牛刀(爬取学校通知公告)
【python基础】函数-初识函数
【python基础】函数-返回值
HTTP请求:requests模块基础使用必知必会
Python初学者友好丨详解参数传递类型
如何有效管理爬虫流量?
2个场景实例讲解GaussDB(DWS)基表统计信息估
常用的 SQL Server 关键字及其含义
动手分析SQL Server中的事务中使用的锁
openGauss内核分析:SQL by pass & 经典执行
一招教你如何高效批量导入与更新数据
天天写SQL,这些神奇的特性你知道吗?
openGauss内核分析:执行计划生成
[IM002]Navicat ODBC驱动器管理器 未发现数据
初入Sql Server 之 存储过程的简单使用
SQL Server -- 解决存储过程传入参数作为s
关于JS定时器的整理
JS中使用Promise.all控制所有的异步请求都完
js中字符串的方法
import-local执行流程与node模块路径解析流程
检测数据类型的四种方法
js中数组的方法,32种方法
前端操作方法
数据类型
window.localStorage.setItem 和 localStorage.setIte
如何完美解决前端数字计算精度丢失与数