日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

反射学习系列3-反射实例应用

發布時間:2023/12/9 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 反射学习系列3-反射实例应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

反射學習系列目錄

反射學習系列1-反射入門

反射學習系列2-特性(Attribute)

反射學習系列3-反射實例應用

作者

例子這個東西其實挺難弄得,弄個簡單的,雖然能說明問題但卻容易讓人覺得沒實用價值,弄個有實用價值卻又往往牽扯很多別的技術甚至牽扯很多業務邏輯,看起來很復雜很難懂。在這里我盡量追求幾個有實用價值又不復雜的例子。
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、插件編程技術
插件是指遵循一定的接口規范、可以動態加載和運行的程序模塊。從上面的例子可以看出,通過反射可以非常方便的動態加載程序集。因此,利用反射的動態加載代碼能力,可以很容易的實現插件。插件編程的要點是使用接口來定義插件的功能特征。插件的宿主程序通過接口來確認、裝載和執行插件的功能,實現插件功能的所有類都必須實現定義插件的接口。

這里只是選貼一部分代碼,詳細分析請看源碼

結構圖

?

接口部分

?

接口
public?interface?IHost
????{
????????List
<ILog>?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?List<ILog>?plugins?=?new?List<ILog>();
????????
#region?IHost?成員

????????
public?List<ILog>?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,在綁定其值的時候絕大多數情況下我們做的都是同樣的事情,獲得數據源,根據數據源中的某些列綁定控件,下邊我們來說說通用情況的處理方式。我們只需要提供數據集合,以及需要綁定到控件的兩個屬性(text,value)名即可。

?

Code
public?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?Add<T>(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?BindTo<T>(IEnumerable<T>?list,?string?nameStr,?string?valueStr)
????????{
????????????Clear();
????????????
foreach?(var?item?in?list)
????????????{
????????????????Add
<T>(item,?nameStr,?valueStr);
????????????}
????????}


????????
public?string?SelectValue
????????{
????????????
get
????????????{
????????????????
return?underlyingList.SelectedValue;
????????????}
????????????
set
????????????{
????????????????underlyingList.SelectedValue
=value;
????????????}
????????}
????}
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;?}
????????}
????}

總結

以上是生活随笔為你收集整理的反射学习系列3-反射实例应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。