静态网站怎么制作,wordpress 页面加载时间 查询次数_和内存,域名 网站 区别,合肥网络推广公司哪家好反射学习系列目录 反射学习系列1-反射入门 反射学习系列2-特性#xff08;Attribute#xff09; 反射学习系列3-反射实例应用 作者 例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务… 反射学习系列目录 反射学习系列1-反射入门 反射学习系列2-特性Attribute 反射学习系列3-反射实例应用 作者 例子这个东西其实挺难弄得,弄个简单的,虽然能说明问题但却容易让人觉得没实用价值,弄个有实用价值却又往往牵扯很多别的技术甚至牵扯很多业务逻辑,看起来很复杂很难懂。在这里我尽量追求几个有实用价值又不复杂的例子。 1、使用反射通过读取配置文件来动态的创建相关类的对象 我们先来看看Main函数和需要动态加载的对象在同一个程序集的情况 结构图 接口 接口interface ILog { bool Write(string message); bool Write(Exception ex); } TextFileLogclass 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; } } XmlFileLogclass 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 LogTime DateTime.Now.ToLocalTime().ToString() /TimeMessage 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 version1.0 encodingutf-8 ?configuration appSettings add keyLogType valueLogClassLibrary.TextFileLog/ !-- 本程序集配置 add keyLogType valueConsoleApplication2.Log例子.TextFileLog/ -- !-- XmlFileLog TextFileLog-- add keyLogTarget valuec:\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、插件编程技术 插件是指遵循一定的接口规范、可以动态加载和运行的程序模块。从上面的例子可以看出通过反射可以非常方便的动态加载程序集。因此利用反射的动态加载代码能力可以很容易的实现插件。插件编程的要点是使用接口来定义插件的功能特征。插件的宿主程序通过接口来确认、装载和执行插件的功能实现插件功能的所有类都必须实现定义插件的接口。 这里只是选贴一部分代码详细分析请看源码 结构图 接口部分 接口public interface IHost { ListILog Plugins { get; } int LoadPlugins(string path); ILog GetLog(string name); } public interface ILog { bool Write(string message); bool Write(Exception ex); } 宿主实现 宿主实现 public class Host : IHost { private ListILog plugins new ListILog(); #region IHost 成员 public ListILog Plugins { get { return plugins; } } public int LoadPlugins(string path) { string[] assemblyFiles Directory.GetFiles(path, *.dll); foreach (var file in assemblyFiles) { Assembly assembly Assembly.LoadFrom(file); foreach (var type in assembly.GetExportedTypes()) { if (type.IsClass typeof(ILog).IsAssignableFrom(type)) { ILog plugin Activator.CreateInstance(type) as ILog; plugins.Add(plugin); } } } return plugins.Count; } public ILog GetLog(string name) { foreach (var item in plugins) { if (item.GetType().ToString()name) { return item; } } return null; } #endregion } ILog的实现和上例基本一样请参考 主程序代码 主程序代码static void Main(string[] args) { Host.Host host new Host.Host(); host.LoadPlugins(.); InterfaceLayer.ILog log host.GetLog(ConfigurationManager.AppSettings[LogType].ToString()); log.Write(new Exception(异常测试)); } 插件编程源码下载 源码下载 3、分析对象得到对象中的属性值 大家使用应都用过asp.net中的DropdownList在绑定其值的时候绝大多数情况下我们做的都是同样的事情获得数据源根据数据源中的某些列绑定控件下边我们来说说通用情况的处理方式。我们只需要提供数据集合以及需要绑定到控件的两个属性textvalue名即可。 Codepublic class DDlControl { private ListControl underlyingList; public DDlControl(ListControl underlyingList) { this.underlyingList underlyingList; } public void Add(IDDL ddl) { underlyingList.Items.Add(new ListItem(ddl.Name, ddl.Value)); } public void AddT(T t, string nameStr, string valueStr) { string name Convert.ToString(t.GetType().InvokeMember (nameStr, System.Reflection.BindingFlags.GetProperty, null, t, null)); string value Convert.ToString(t.GetType().InvokeMember (valueStr, System.Reflection.BindingFlags.GetProperty, null, t, null)); Add(new DDLStruct(name,value)); } public void Clear() { underlyingList.Items.Clear(); } public IDDL SelectedItem { get { ListItem item underlyingList.SelectedItem; return new DDLStruct(item.Text, item.Value); } } public void BindToT(IEnumerableT list, string nameStr, string valueStr) { Clear(); foreach (var item in list) { AddT(item, nameStr, valueStr); } } public string SelectValue { get { return underlyingList.SelectedValue; } set { underlyingList.SelectedValuevalue; } } }public struct DDLStruct { public DDLStruct(string name, string value) { this.name name; this.value value; } private string name; private string value; public string Name { get { return name; } } public string Value { get { return value; } } }