乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Net反射在項(xiàng)目中的應(yīng)用

       昵稱10504424 2013-05-13
      Net反射在項(xiàng)目中的應(yīng)用

      反射的概念和基本原理msdn很詳細(xì),這個(gè)文章主要說(shuō)說(shuō)反射在我的項(xiàng)目中的應(yīng)用

      反射用的比較多一個(gè)概念是程序集,也可以認(rèn)為就是dll類庫(kù),程序集是所有類型的集合,它還有一個(gè)重要的東西就是元數(shù)據(jù)。JIT就是利用程序集的TypeRef和AssemblyRef等元數(shù)據(jù)來(lái)確定所引用的程序集及類型,這些元數(shù)據(jù)包括名稱、版本、語(yǔ)言文化和公鑰標(biāo)記等,JIT就是根據(jù)這些信息來(lái)加載一個(gè)程序集到應(yīng)用程序域中。如果要自己加載一個(gè)程序集,可以調(diào)用類型Assembly的LoadXXX系列方法。從Assembly中可以讀到這個(gè)dll中所以類,類的繼承接口,類的方法,屬性,字段,事件等等。

       

      反射和接口

      反射是在運(yùn)行中動(dòng)態(tài)的創(chuàng)建需要的類,接口和接口的方法在編譯的時(shí)候已經(jīng)確定了,接口的實(shí)現(xiàn)依賴他的繼承類,有了繼承類,接口才能實(shí)例化使用定義好的方法。

      反射就是把接口的實(shí)例化推遲到運(yùn)行階段。所以反射一般和接口搭配使用。

       

      應(yīng)用場(chǎng)景一:?jiǎn)蝹€(gè)接口對(duì)應(yīng)多個(gè)實(shí)現(xiàn)

      這個(gè)場(chǎng)景比較多,而且在抽象工廠模式中我覺(jué)得用的很多,典型的例子是數(shù)據(jù)讀取層。
      一個(gè)項(xiàng)目可能用到SqlSever,Access,Orace或者Txt,XML來(lái)當(dāng)存取數(shù)據(jù),他們的方法都是統(tǒng)一,比如增,刪,修,讀等

      這個(gè)時(shí)候就是定義一個(gè)IDataAccess接口,這個(gè)接口定義了統(tǒng)一的方法,增,刪,修,讀等,然后分別用不同的實(shí)現(xiàn)類來(lái)繼承這個(gè)接口,

      比如SqlServer類,XmL類,定義為SqlServerDataAccess,XMLDataAccess,他們都繼承IDataAccess

      在應(yīng)用的時(shí)候項(xiàng)目可以通過(guò)簡(jiǎn)單的修改或者配置來(lái)使用Sqlserver或者XML數(shù)據(jù)庫(kù),這個(gè)時(shí)候就可以使用反射來(lái)決定接口IDataAccess到底使用哪個(gè)實(shí)現(xiàn)類

      抽象工廠模式中使用配置文件來(lái)設(shè)置使用Sqlserver還是XML數(shù)據(jù)實(shí)現(xiàn)類。在配置文件中定義“程序集和命名空間類名”的信息,這樣通過(guò)修改配置文件就可以決定使用

      Sqlserver還是XML數(shù)據(jù)實(shí)現(xiàn)類

      public IDataAccess CreateDatAccess()

      {

      IDataAccess IDA =(IDataAccess)Assembly.Load("配置節(jié)點(diǎn)程序集").CreateInstance("命名空間.Sqlserver");

      //IDataAccess IDA =(IDataAccess)Assembly.Load("配置節(jié)點(diǎn)程序集").CreateInstance("命名空間.XML");

      return IDA;

      }

      應(yīng)用場(chǎng)景二:多個(gè)接口和多個(gè)實(shí)現(xiàn)類

      這個(gè)例子的完全可以使用第一個(gè)場(chǎng)景的方案來(lái)解決,但是由于接口多,實(shí)現(xiàn)類,實(shí)現(xiàn)起來(lái)比較復(fù)雜

      這個(gè)例子說(shuō)的是多個(gè)接口,每個(gè)接口可能有一個(gè)實(shí)現(xiàn)類,也可能有多個(gè)實(shí)現(xiàn)類。

      基本實(shí)現(xiàn)思路通過(guò)遍歷bin下的文件夾,得到dll信息,把接口和對(duì)應(yīng)的實(shí)現(xiàn)類組織到字典集合中,然后根據(jù)一個(gè)接口信息就可以得到實(shí)現(xiàn)類,實(shí)現(xiàn)接口的動(dòng)態(tài)實(shí)例化

      如果接口只有一個(gè)實(shí)現(xiàn)類就直接取得這個(gè)類,如果接口有多個(gè)實(shí)現(xiàn)類那就傳遞一個(gè)類的名稱來(lái)明確要求讀取哪個(gè)類

      具體實(shí)現(xiàn),為了更好的項(xiàng)目結(jié)構(gòu),建立一個(gè)接口dll,然后不同的接口對(duì)應(yīng)不同的dll類庫(kù),實(shí)現(xiàn)類的項(xiàng)目名稱最好有個(gè)規(guī)格,方便在遍歷文件夾的時(shí)候讀取特定名稱的dll,加快遍歷速度。

      項(xiàng)目結(jié)構(gòu)如圖:

       

      在ConsoleApplication2.Framework定義兩個(gè)接口

      在ConsoleApplication2.Impl.Product定義產(chǎn)品接口實(shí)現(xiàn)類

      在ConsoleApplication2.Impl.Car定義ICar實(shí)現(xiàn)類

       

      然后開始重點(diǎn)代碼部分

      1.建立接口和實(shí)現(xiàn)類的對(duì)應(yīng)關(guān)系,保存到字典集合中

      復(fù)制代碼
      static Dictionary<Type, List<Type>> dictionary = new Dictionary<Type, List<Type>>();
      public
      static void
      GetInterfaceAndType()
      {
      string s =
      Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
      foreach (var file in Directory.GetFiles(s, "ConsoleApplication2.Impl.*.dll"
      ))//遍歷程序下的類似命名規(guī)范的dll,
      {
      var ass =
      Assembly.Load(File.ReadAllBytes(file));
      //得到程序集dll Console.WriteLine(ass.FullName);
      foreach (Type type in ass.GetTypes().Where(p=>
      p.IsClass))//遍歷程序集中類
      { Console.WriteLine(type.FullName); Type[] interfaces
      =
      type.GetInterfaces();//該類繼承的接口,可能是多個(gè)接口
      foreach (Type inter in
      interfaces)//建立接口和實(shí)現(xiàn)類的對(duì)應(yīng)關(guān)系,一個(gè)接口可能多個(gè)實(shí)現(xiàn)類
      {
      if (!
      dictionary.ContainsKey(inter))
      { dictionary.Add(inter,
      new List<Type>
      ());
      }
      dictionary[inter].Add(type);
      }
      }
      }
      }
      復(fù)制代碼

      在根據(jù)接口讀取實(shí)現(xiàn)類,因?yàn)榻涌诓煌?,所以用泛型?lái)實(shí)現(xiàn)

      復(fù)制代碼
       
      //specifiedImplType參數(shù)可以為空,如果一個(gè)接口有多個(gè)實(shí)現(xiàn)類的時(shí)候,需要特別指定使用哪個(gè)實(shí)現(xiàn)類
      public static T GetImpTypeByInterface<T>(string specifiedImplType = "") where T : class {
      Type interfaceType
      = typeof(T);//接口
      if (dictionary.Count > 0 &&
      dictionary.ContainsKey(interfaceType))
      { Type implType
      = null
      ; if (specifiedImplType == "")//讀字典集合中根據(jù)接口key得到實(shí)現(xiàn)類Type
      {
      implType
      =
      dictionary[interfaceType].First();
      }
      else

      {
      implType
      = dictionary[interfaceType].Where(p => p.Name == specifiedImplType).FirstOrDefault();
      }
      return Activator.CreateInstance(implType) as
      T;//Activator.CreateInstance該語(yǔ)法創(chuàng)建類的實(shí)例,并且As 轉(zhuǎn)換為T類型
      }
      else
      { throw new Exception("沒(méi)有繼承對(duì)象"); } }
      復(fù)制代碼

      最后測(cè)試運(yùn)行

        本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

        請(qǐng)遵守用戶 評(píng)論公約

        類似文章 更多