Net反射在項目中的應用
反射的概念和基本原理msdn很詳細,這個文章主要說說反射在我的項目中的應用
反射用的比較多一個概念是程序集,也可以認為就是dll類庫,程序集是所有類型的集合,它還有一個重要的東西就是元數據。JIT就是利用程序集的TypeRef和AssemblyRef等元數據來確定所引用的程序集及類型,這些元數據包括名稱、版本、語言文化和公鑰標記等,JIT就是根據這些信息來加載一個程序集到應用程序域中。如果要自己加載一個程序集,可以調用類型Assembly的LoadXXX系列方法。從Assembly中可以讀到這個dll中所以類,類的繼承接口,類的方法,屬性,字段,事件等等。
反射是在運行中動態的創建需要的類,接口和接口的方法在編譯的時候已經確定了,接口的實現依賴他的繼承類,有了繼承類,接口才能實例化使用定義好的方法。
反射就是把接口的實例化推遲到運行階段。所以反射一般和接口搭配使用。
這個場景比較多,而且在抽象工廠模式中我覺得用的很多,典型的例子是數據讀取層。
一個項目可能用到SqlSever,Access,Orace或者Txt,XML來當存取數據,他們的方法都是統一,比如增,刪,修,讀等
這個時候就是定義一個IDataAccess接口,這個接口定義了統一的方法,增,刪,修,讀等,然後分別用不同的實現類來繼承這個接口,
比如SqlServer類,XmL類,定義為SqlServerDataAccess,XMLDataAccess,他們都繼承IDataAccess
在應用的時候項目可以通過簡單的修改或者配置來使用Sqlserver或者XML數據庫,這個時候就可以使用反射來決定接口IDataAccess到底使用哪個實現類
抽象工廠模式中使用配置文件來設置使用Sqlserver還是XML數據實現類。,這樣通過修改配置文件就可以決定使用
Sqlserver還是XML數據實現類
public IDataAccess CreateDatAccess()
{
IDataAccess IDA =(IDataAccess)Assembly.Load("配置節點程序集").CreateInstance("命名空間.Sqlserver");
//IDataAccess IDA =(IDataAccess)Assembly.Load("配置節點程序集").CreateInstance("命名空間.XML");
return IDA;
}
這個例子的完全可以使用第一個場景的方案來解決,但是由於接口多,實現類,實現起來比較復雜
這個例子說的是多個接口,每個接口可能有一個實現類,也可能有多個實現類。
項目結構如圖:
在ConsoleApplication2.Framework定義兩個接口
在ConsoleApplication2.Impl.Product定義產品接口實現類
在ConsoleApplication2.Impl.Car定義ICar實現類
{
Console.WriteLine( }
}
{
Console.WriteLine( }
}
然後開始重點代碼部分
1.建立接口和實現類的對應關系,保存到字典集合中
public {
s = ( file Directory.GetFiles(s, { ass =//得到程序集dll Console.WriteLine(ass.FullName);
(Type type ass.GetTypes().Where(p=> { Console.WriteLine(type.FullName); Type[] interfaces = (Type inter {
(! { dictionary.Add(inter, List<Type> }
dictionary[inter].Add(type);
}
}
}
}
在根據接口讀取實現類,因為接口不同,所以用泛型來實現
//specifiedImplType參數可以為空,如果一個接口有多個實現類的時候,需要特別指定使用哪個實現類
T GetImpTypeByInterface<T>( specifiedImplType = ) where T : class Type interfaceType = (dictionary.Count > &&{ Type implType = (specifiedImplType == {
implType = }
implType = dictionary[interfaceType].Where(p => p.Name == }
Activator.CreateInstance(implType) }
Exception(
最後測試運行
= GetImpTypeByInterface<ICar>(); ICar iCar = GetImpTypeByInterface<ICar>(“QQCar”); iCar.Run();
這樣就可以直接根據接口類找到他對應的實現類,