最近的天氣是相當的冷,冷的本來開這個博客時想寫的大作(連標題都想好了)都懶得動手了。也罷,這第一篇博文還是寫點輕松愉快的內容吧。
(呃,基本上就這感覺吧)
也罷,這個系列就寫點基本沒人用到的冷知識好了。說是系列,其實也就是想到哪寫到哪,正式的說法就是“每集都是一個獨立的故事”。
今天就說說.Net中通過反射取得某個類型時,我們怎么知道這個類型在硬盤上的哪個角落?比如說,假如我們需要要求服務端動態載入某個數據源,那服務端怎么知道數據源在哪?
網上大部分的教程都寫著,可以使用Assembly.Load方法來先加載程序集,然后再用Assembly.GetType或者Assembly.GetTypes方法處理。
這個方法很好很實用,基本上也就夠了。不過如果這么無聊,也就算不上冷知識,更沒有必要寫這些了。
如果有辦法自動搜索程序集里面有沒有暴露對應的類型,我們憑啥還要自行載入程序集?難道小又軟的那群人也這么無聊?
其實還真是有辦法解決這個問題的。
(呃,放錯圖了,請自行腦補多啦A夢掏道具時的聲音)Type.GetType,就是你了。
那么,這個方法有什么神奇的呢?Type.GetType有多個重載,其中除了一個沒有參數的以外,剩下的幾個重載要求至少一個字符串類型的typeName進行搜索,具體參見MSDN。比如下面這個例子:
using System;namespace Consoleapplication2{ internal class PRogram { private static void Main(string[] args) { Type addedInRuntimeType = Type.GetType("LibA.TestClass, LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); foreach (var propertyInfo in addedInRuntimeType.GetProperties()) { Console.WriteLine(propertyInfo.Name); } } }}
假設目錄下我們有一個LibA.dll,LibA.dll里面包含了一個類LibA.TestClass,以上代碼就能取得里面的全部屬性名,接下來要對這個類型做什么羞羞的事情那就各位看官自行決定咯。
但是,目前還是有一個限制沒有解決。GetType方法的參數中和文件有關的就只有typeName了。可是這貨并沒有指定路徑。如果要加載的類型所在的程序集在GAC中或者在當前程序集路徑下那還好,如果因為各(xian)種(de)原(dan)因(teng)需要放到子目錄該怎么辦呢?比如說要在子目錄“runtime”以及“runtme2”下進行搜索又該怎么辦呢?還是直接放代碼吧:
using System;namespace ConsoleApplication2{ internal class Program { private static void Main(string[] args) { AppDomain.CurrentDomain.AppendPrivatePath("runtime"); AppDomain.CurrentDomain.AppendPrivatePath("runtime2"); Type addedInRuntimeType = Type.GetType("LibA.TestClass, LibA, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"); foreach (var propertyInfo in addedInRuntimeType.GetProperties()) { Console.WriteLine(propertyInfo.Name); } } }}AppDomain.CurrentDomain.AppendPrivatePath可以增加CLR搜索的路徑,不過這個方法已經被標記為obsolete了。請自行無視這個警告吧。或者按如下代碼處理:
#pragma warning disable 618 AppDomain.CurrentDomain.AppendPrivatePath("runtime");#pragma warning restore 618繼續說點,其實這個路徑也可以寫在配置文件中的。MSDN說明在此,例子如下:
<?xml version="1.0" encoding="utf-8"?><configuration> <runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <probing privatePath="runtime;runtime2" /> </assemblyBinding> </runtime></configuration>
到這里,這個無聊的問題我們就已經完全解決了。下回的內容……呃……完全木有想法
。
|
新聞熱點
疑難解答