最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

在C#中如何獲取程序集

 更新時間:2024年03月16日 09:05:41   作者:錢行慕  
某一天我正在寫一些反射代碼,目的是遍歷所有的程序集來查找一個特定的接口,然后在Startup中調(diào)用其上的一個方法,這篇文章主要介紹了在C#中如何獲取程序集,需要的朋友可以參考下

某一天我正在寫一些反射代碼,目的是遍歷所有的程序集來查找一個特定的接口,然后在Startup中調(diào)用其上的一個方法??雌饋磉@個功能似乎很簡單,但是在現(xiàn)實(shí)中,卻沒有一個清晰的,簡單的,適合各種情形的方式來獲取一個程序集。這篇文章獲取對某些人來說非常的枯燥,但是如果我能夠幫助哪怕一個人來解決此類問題,那么這篇文章也是值得的。

說真的,由于有多種獲取程序集的方法,我將不會說”使用這個方法”。很有可能,對于你的特定的工程來說,也許只有一種方式可以工作,所以依賴其他的方式是毫無意義的。讓我們簡單的對所有的方式做個測試,然后看看哪一個方法是最合理的。

使用AppDomain.GetAssemblies

你可能會遇到的第一個選項(xiàng)是AppDomain.GetAssemblies。它(看似)加載了在AppDomain中的所有程序集,基本上可以說加載了你項(xiàng)目使用到的每一個程序集。但是卻存在著大量的警告。在.NET中程序集是延遲加載到AppDomain中的,它不可能一次性加載所有的程序集,而是等你調(diào)用了一個程序集中的方法/類的時候,它才會將它加載進(jìn)來--也就是即時加載。這是合理的,因?yàn)槿绻銖牟皇褂靡粋€程序集的話,是沒有理由加載它的。

但問題是在你調(diào)用AppDomain.GetAssemblies()的那個時間點(diǎn)上,如果你并沒有調(diào)用某個特定的程序集的方法,它便不會被加載。現(xiàn)在如果你要為了Startup方法得到所有的程序集,很有可能你還沒有調(diào)用到那個程序集,這就意味著它還沒有加載到AppDomain,所以便獲取不到這個接口方法。

用代碼來說:

AppDomain.CurrentDomain.GetAssemblies(); // Does not return SomeAssembly as it hasn't been called yet.
SomeAssembly.SomeClass.SomeMethod();
AppDomain.CurrentDomain.GetAssemblies(); // Will now return SomeAssembly.

雖然這看起來是一個很有吸引力的選項(xiàng),但是要知道,對于這個方法來說,時機(jī)是一切。

使用AssemblyLoad事件

因?yàn)槟悴荒艽_保當(dāng)你調(diào)用CurrentDomain.GetAssemblies()時所有程序集都被加載了,而實(shí)際上當(dāng)AppDomain加載另一個程序集的時候有一個事件會運(yùn)行?;旧险f,當(dāng)一個程序集被延遲加載的時候,你可以被通知到。它看起來像是這樣:

AppDomain.CurrentDomain.AssemblyLoad += (sender, args) =>
{
    var assembly = args.LoadedAssembly;
};

如果你只是想當(dāng)程序集加載的時候檢查下一些東西,那這或許是一個不錯的解決方案,但是這個過程在某個特定的點(diǎn)并不是必然會發(fā)生(在你的.NET Core app的Startup.cs類中并不會發(fā)生)。

這個方法的另一個問題是到你添加你的事件處理器的那個時刻,并不能保證程序集還沒有被加載(事實(shí)上它們很可能已經(jīng)加載過了)。所以呢?你需要付出雙份的努力,首先添加你的事件處理器,之后迅速的檢查AppDomain.CurrentDomain.GetAssemblies,找到已經(jīng)被加載了的東西。

這是一個完美的解決方案,但是如果你習(xí)慣于使用延遲加載的程序集來做事的話,這就不能正常工作了。

使用 GetReferencedAssemblies()

排名中的下一個是GetReferencedAssemblies()。本質(zhì)上你可以通過一個程序集,比如你的入口點(diǎn)程序集,一般來說便是你的web項(xiàng)目,來得到所有引用的程序集。

其代碼本身看起來像是這樣:

Assembly.GetEntryAssembly().GetReferencedAssemblies();

再一次,看起來像是在玩把戲,但是這個方法有另一個很大的問題。在許多項(xiàng)目中會有一個“模式分離”的概念,比如 Web Project>>Service Project>>Data Project。Web Project本身并不直接引用Data Project。而當(dāng)你調(diào)用“GetReferencedAssemblies”時其意味著直接引用。因此如果你期望在程序集列表中得到Data Project,你將會失望不已。

所以,再一次的,在一些情況下可以正常工作,但并不是一個普遍的解決方案。

循環(huán)GetReferencedAssemblies()

使用GetReferencedAssemblies()的另一個選擇是創(chuàng)建一個方法來遍歷所有的程序集。類似于這樣:

public static List GetAssemblies()
{
    var returnAssemblies = new List();
    var loadedAssemblies = new HashSet();
    var assembliesToCheck = new Queue();
    assembliesToCheck.Enqueue(Assembly.GetEntryAssembly());
    while(assembliesToCheck.Any())
    {
        var assemblyToCheck = assembliesToCheck.Dequeue();
        foreach(var reference in assemblyToCheck.GetReferencedAssemblies())
        {
            if(!loadedAssemblies.Contains(reference.FullName))
            {
                var assembly = Assembly.Load(reference);
                assembliesToCheck.Enqueue(assembly);
                loadedAssemblies.Add(reference.FullName);
                returnAssemblies.Add(assembly);
            }
        }
    }
    return returnAssemblies;
}

這個方法的邊界處理得有點(diǎn)粗糙,但是它的確可以工作并且意味著在Startup方法中,你可以立即看到所有的程序集。

關(guān)于這個方法你可能會被卡住的一次是如果你正在動態(tài)加載程序集,并且它們實(shí)際上并不會被任何項(xiàng)目所引用。對于這種情況,你需要下一個方法。

目錄DLL加載

一個很粗糙的獲取所有解決方案dll的方式是將它們加載出你的bin文件夾。看起來像是這樣:

public static Assembly[] GetSolutionAssemblies()
{
    var assemblies = Directory.GetFiles(AppDomain.CurrentDomain.BaseDirectory, "*.dll")
                        .Select(x => Assembly.Load(AssemblyName.GetAssemblyName(x)));
    return assemblies.ToArray();
}

它可以正常工作但的確是一個粗糙的解決方案。但是使用這個方式的一個最大的好處是一個dll只需要簡單的放置在需要加載的目錄中就可以。因此如果你出于任何原因動態(tài)的加載DLLs,對于你來說,這很可能是唯一的方法(除過在AppDomain中監(jiān)聽AssemblyLoad)。

這是做這件事情的看起來像惡作劇的方式之一。但是很可能你已經(jīng)被阻擋到角落之中而這正是解決問題的唯一方式。

僅僅得到“我的”程序集

使用這些方法中的任何一種,您會很快發(fā)現(xiàn)你正在將Nuget下的每個程序集加載到你的項(xiàng)目中,包括Nuget包、.NET核心庫甚至運(yùn)行時特定的dll。在.NET世界中,程序集就是程序集。沒有“是的,但這是我的程序集”并且它們很特別的概念。

過濾的唯一方法就是檢查名字。您可以將其作為白名單來執(zhí)行,因此如果解決方案中的所有項(xiàng)目都以“MySolution”開頭。因而你可以像這樣來進(jìn)行過濾:

Assembly.GetEntryAssembly().GetReferencedAssemblies().Where(x => x.Name.StartsWith("MySolution."))

或者你可以選擇一個黑名單選項(xiàng),這個選項(xiàng)并不真正限制你的程序集,但至少可以減少你正在加載/檢查/處理的程序集的數(shù)量。就像這樣:

Assembly.GetEntryAssembly().GetReferencedAssemblies()
.Where(x => !x.Name.StartsWith("Microsoft.") && !x.Name.StartsWith("System."))

黑名單可能看起來很蠢,但在某些情況下,如果您正在構(gòu)建一個實(shí)際上不知道最終解決方案名稱的庫,那么這是減少您試圖加載的內(nèi)容的唯一方法。

到此這篇關(guān)于在C#中如何獲取程序集的文章就介紹到這了,更多相關(guān)C#獲取程序集內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • c#實(shí)現(xiàn)無標(biāo)題欄窗口的拖動

    c#實(shí)現(xiàn)無標(biāo)題欄窗口的拖動

    本篇文章是對c#中實(shí)現(xiàn)無標(biāo)題欄窗口拖動的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • 實(shí)例代碼講解c# 線程(下)

    實(shí)例代碼講解c# 線程(下)

    這篇文章主要介紹了c# 線程的的相關(guān)資料,文中示例代碼非常細(xì)致,對大家的學(xué)習(xí)有很大幫助,感興趣的朋友可以了解下
    2020-06-06
  • c#獲取gridview的值代碼分享

    c#獲取gridview的值代碼分享

    這篇文章主要介紹了C#如何在事件中獲得GridView里面TextBox的值,大家參考使用吧
    2013-12-12
  • c#入門之循環(huán)語句使用詳解(for循環(huán)、do/while)

    c#入門之循環(huán)語句使用詳解(for循環(huán)、do/while)

    這篇文章主要介紹了c#入門之循環(huán)語句使用詳解,有for循環(huán)和do/while的示例,需要的朋友可以參考下
    2014-04-04
  • C#調(diào)用exe文件的方法詳解

    C#調(diào)用exe文件的方法詳解

    這篇文章主要為大家詳細(xì)介紹了C#調(diào)用exe文件的相關(guān)方法,文中的示例代碼講解詳細(xì),具有一定的借鑒價值,有需要的小伙伴可以參考一下
    2024-04-04
  • C#實(shí)現(xiàn)拼圖游戲

    C#實(shí)現(xiàn)拼圖游戲

    這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)拼圖游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • C#實(shí)現(xiàn)DataTable數(shù)據(jù)行列轉(zhuǎn)換

    C#實(shí)現(xiàn)DataTable數(shù)據(jù)行列轉(zhuǎn)換

    這篇文章介紹了C#實(shí)現(xiàn)DataTable數(shù)據(jù)行列轉(zhuǎn)換的方法,文中通過示例代碼介紹的非常詳細(xì)。對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-04-04
  • C#進(jìn)度軸控件分享

    C#進(jìn)度軸控件分享

    這里給大家介紹的是使用C#實(shí)現(xiàn)的進(jìn)度軸的方法和示例,非常的實(shí)用,有需要的小伙伴可以參考下。
    2015-06-06
  • 淺談C#中的值類型和引用類型

    淺談C#中的值類型和引用類型

    在C#中值類型的變量直接存儲數(shù)據(jù),而引用類型的變量持有的是數(shù)據(jù)的引用,數(shù)據(jù)存儲在數(shù)據(jù)堆中。下面我們來簡單談?wù)凜#中的值類型和引用類型
    2016-06-06
  • Unity使用ScrollRect制作搖桿

    Unity使用ScrollRect制作搖桿

    這篇文章主要為大家詳細(xì)介紹了Unity使用ScrollRect制作搖桿,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-04-04

最新評論

彰武县| 天柱县| 工布江达县| 若尔盖县| 香港 | 虹口区| 正镶白旗| 慈溪市| 明光市| 肇州县| 仪征市| 芜湖县| 鸡西市| 成都市| 曲靖市| 宁安市| 巴南区| 双江| 婺源县| 从江县| 黄龙县| 沁阳市| 望谟县| 台中市| 额济纳旗| 吉安市| 分宜县| 通化县| 安丘市| 上高县| 吉林省| 嘉义县| 百色市| 宣恩县| 华阴市| 沁源县| 临安市| 新源县| 资中县| 常德市| 资中县|