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

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

    • 分享

      使用Fusion解析未引用的部分類型名稱

       碼農(nóng)9527 2021-04-29

      最近,我的任務(wù)是編寫一個(gè)數(shù)據(jù)提取/報(bào)告框架,該框架將使客戶端應(yīng)用程序能夠定義要執(zhí)行的存儲(chǔ)過程,并將結(jié)果通過電子郵件發(fā)送給感興趣的各方。使該項(xiàng)目變得有趣的是允許用戶從一組查找表,Web服務(wù)數(shù)據(jù)和應(yīng)用程序派生數(shù)據(jù)中指定參數(shù)值的要求。在沒有任何外部引用的情況下,檢索Web服務(wù)或應(yīng)用程序派生數(shù)據(jù)的要求需要一種機(jī)制來執(zhí)行未引用程序集中的方法。

      web

          本文概述了我的方法,該方法允許框架代碼通過部分類型名解析來執(zhí)行未引用程序集中的方法。

          問題

          查找表數(shù)據(jù)的預(yù)填充非常簡(jiǎn)單-從表中選擇Id和Value字段-這是通過一個(gè)簡(jiǎn)單的ParameterLookup表實(shí)現(xiàn)的。但是,當(dāng)有時(shí)間用Web服務(wù)數(shù)據(jù)或特定于應(yīng)用程序的數(shù)據(jù)預(yù)先填充查找時(shí),我們需要某種機(jī)制來執(zhí)行客戶端應(yīng)用程序中的方法。在沒有對(duì)客戶端應(yīng)用程序的任何引用的情況下,我們需要一種機(jī)制來解析和執(zhí)行客戶端應(yīng)用程序代碼。我們實(shí)現(xiàn)的方法是LookupClass在ParameterLookup表中包含一個(gè)字段,并讓框架代碼解析類型并執(zhí)行該search方法。

          有許多常用的方法允許.NET代碼解析和執(zhí)行未引用類型的方法,盡管并非所有方法都適用于所有環(huán)境。當(dāng)宿主進(jìn)程是COM+進(jìn)程時(shí),Type.GetType()可以將調(diào)用與部分限定的類型名稱(即MyCompany.MyApplication.Search.Lookup.SomeLookup,MyCompany.MyApplication)一起使用。但是,當(dāng)主機(jī)進(jìn)程是IIS時(shí),必須指定完全限定的類型名稱(“類型名稱”,“程序集名稱”,“版本”,“區(qū)域性”,“公鑰”),或者該程序集必須存在于Web程序包的/bin目錄中。

          不希望ParameterLookup每次執(zhí)行新版本的應(yīng)用程序時(shí)都強(qiáng)制客戶端應(yīng)用程序更新表,我們需要一種僅使用Type和Assembly名稱部分的機(jī)制。

          解決方案

          如果您沒有完全限定的類型名稱(類型名稱,程序集類型,版本,區(qū)域性和公共密鑰),則在未引用的程序集中定義的類型可以是正確的PITA。

          例如,類型Microsoft.Build.BuildEngine.Engine類型的完全限定名稱為Microsoft.Build.BuildEngine.Engine,Microsoft.Build.Engine,Culture=neutral,Version=4.0.0.0,PublicKeyToken=b03f5f7f11d50a3a(真是令人討厭?。?duì)于相對(duì)穩(wěn)定的組件,可以在配置表/文件中指定完全限定的類型名稱,但是對(duì)于版本號(hào)更改為相對(duì)不穩(wěn)定的不穩(wěn)定組件(例如,來自客戶端應(yīng)用程序的組件),您該怎么做?每個(gè)版本?

          Type.GetType()

          該Type.GetType()功能可用于加載在項(xiàng)目中引用或在程序集搜索路徑中的程序集。

      Type t = Type.GetType("MyCompany.MyApplication.Lookup.SomeLookup, MyCompany.MyApplication "); 1復(fù)制代碼類型:[html]

          由于框架代碼不會(huì)引用該程序集,因此我們唯一的希望是該程序集位于程序集搜索路徑中。盡管這種情況是可能的,但肯定不能保證。

          該解決方案必須丟棄。

          如果我們?yōu)門ype.GetType()函數(shù)提供完全限定的類型名稱該怎么辦?

      Type t = Type.GetType("MyCompany.MyApplication.Lookup.SomeLookup, 
        MyCompany.MyApplication, Culture=neutral, Version=1.0.0.3245, PublicKey= 1e9a8d893e3afa78");12復(fù)制代碼類型:[html]

          此調(diào)用肯定有效,并且類型引用已成功返回。所需要做的就是將此完全合格的類型傳遞給框架代碼-相對(duì)簡(jiǎn)單的練習(xí)。las,當(dāng)重新編譯程序集時(shí),將使用不同的內(nèi)部版本號(hào)(假定您使用的是內(nèi)部版本號(hào))創(chuàng)建該組件的新版本,該調(diào)用將返回原始程序集;否則,將返回原始程序集。不是更新的程序集。這是不理想的。

          該解決方案必須丟棄。

          我需要的是一種無需指定版本號(hào)或無需依靠程序集搜索路徑中的程序集即可解決類型的方法。

          Assembly.LoadFrom()

          該Assembly.LoadFrom()方法看起來很有希望,因?yàn)槲铱梢允褂么撕瘮?shù)來加載程序集而無論其位置如何,并遍歷該程序集中定義的每種類型。

      internal static Type GetTypeFromAssembly(string assemblyName, string typeName)
      {
       Assembly assembly = Assembly.LoadFrom(gacPath);
       Type[] types = assembly.GetTypes();
       
       foreach (Type type in types)
       {
        if (type.FullName == typeName))
         return type;
       }
       return null;
      }123456789101112復(fù)制代碼類型:[html]

          條件if(type.FullName==typeName)使我們不必指定完全限定類型的版本,區(qū)域性或公鑰屬性?,F(xiàn)在,我們可以加載程序集并提取適當(dāng)?shù)念愋鸵怨┦褂谩?/p>

          但是,這導(dǎo)致了代碼和安裝實(shí)現(xiàn)之間的依賴性。如果支持操作員決定修改應(yīng)用程序安裝參數(shù),則可以將軟件安裝到未知位置??梢韵胂?,我們可能要求將軟件安裝到特定位置(例如ProgramFiles),但這會(huì)導(dǎo)致32位/64位問題(ProgramFiles是指“ProgramFiles”還是“ProgramFiles(x86)”?)。

          但我想我快到了。

          融合

          如果將擁有我們所要類型的程序集安裝到全局程序集緩存中,則我們可以利用CLR程序集管理系統(tǒng)為我們加載并找到我們的程序集。

          使用Fusion.dll程序集(有關(guān)詳細(xì)信息,請(qǐng)參閱此鏈接),我們可以創(chuàng)建對(duì)適當(dāng)?shù)腉AC(32位或64位)的引用,并使用該Assembly.LoadFrom()方法安全地加載我們的程序集。

      [DllImport("fusion.dll")]
      internal static extern int CreateAssemblyCache(out IAssemblyCache ppAsmCache, int reserved);12復(fù)制代碼類型:[html]
      private static string GetAssemblyPath(string name)
      {
       if (name == null) 
        throw new ArgumentNullException("name");
       
       string finalName = name;
       AssemblyInfo aInfo = new AssemblyInfo();
       aInfo.cchBuf = 1024; // should be fine...
       aInfo.currentAssemblyPath = new String('\0', aInfo.cchBuf);
       
       IAssemblyCache ac;
       int hr = CreateAssemblyCache(out ac, 0);
       if (hr >= 0)
       {
        hr = ac.QueryAssemblyInfo(0, finalName, ref aInfo);
        if (hr < 0)
         return null;
       }
       
       return aInfo.currentAssemblyPath;
      }123456789101112131415161718192021復(fù)制代碼類型:[html]
      public static Type ResolveType(string assemblyName, string typeName)
      {
       string gacPath = GetAssemblyPath(assemblyName);
       return GetTypeFromAssembly(assemblyName, typeName);
      }12345復(fù)制代碼類型:[html]

          僅使用類型和程序集的名稱,代碼將搜索適合于應(yīng)用程序環(huán)境(x86/x64)的GAC目錄,并返回對(duì)該類型的引用。引用正確的類型后,對(duì)的調(diào)用Activator.CreateInstance()將創(chuàng)建要使用的可用類型。

          使用代碼

          框架定義了要解析的類型必須實(shí)現(xiàn)的接口。

      namespace FrameworkApp
      {
       public interface ILookup
       {
        string Search();
       }
      }1234567復(fù)制代碼類型:[html]

          ...當(dāng)類實(shí)現(xiàn)接口時(shí)。

      public class SearchType1 : ILookup
      {
       public string Search()
       {
        return string.Format("SearchType1.Search() from version {0}", 
         Assembly.GetExecutingAssembly().GetName().Version);
       }
      }12345678復(fù)制代碼類型:[html]

          現(xiàn)在,我們只需要調(diào)用TypeResolver.ResolveType(),創(chuàng)建一個(gè)返回類型的實(shí)例(強(qiáng)制進(jìn)入選擇的接口),最后執(zhí)行所需的方法。

      Type type = TypeResolver.ResolveType("ClientApp.SearchType1,ClientApp");
      ILookup lookup = Activator.CreateInstance(type) as ILookup;
      lookup.Search();123復(fù)制代碼類型:[html]

          局限性

          程序集必須在GAC中注冊(cè)才能使此解決方案生效

          不會(huì)加載不兼容的.NET版本程序集

          將解析為最高版本,而不是最新編譯的版本

        轉(zhuǎn)藏 分享 獻(xiàn)花(0

        0條評(píng)論

        發(fā)表

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

        類似文章 更多