簡體   English   中英

在 AppDomain 中未觸發 AssemblyLoad 事件

[英]AssemblyLoad event is not fired in AppDomain

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;

namespace DefaultAppDomainApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("***** Fun with the default app domain *****\n");
            InitDAD();

            DisplayDADStats();
            Console.WriteLine();

            ListAllAssembliesInAppDomain();

            Console.ReadLine();
        }

        #region Init the default app domain
        private static void InitDAD()
        {
            // This logic will print out the name of any assembly
            // loaded into the applicaion domain, after it has been
            // created. 
            AppDomain defaultAD = AppDomain.CurrentDomain;
            defaultAD.AssemblyLoad += (o, s) =>
                {
                    Console.WriteLine("{0} has been loaded!", s.LoadedAssembly.GetName().Name);
                };
        }
        #endregion

        #region Display basic stats
        private static void DisplayDADStats()
        {
            // Get access to the app domain for the current thread.
            AppDomain defaultAD = AppDomain.CurrentDomain;

            Console.WriteLine("Name of this domain: {0}", defaultAD.FriendlyName);
            Console.WriteLine("ID of domain in this process: {0}", defaultAD.Id);
            Console.WriteLine("Is this the default domain?: {0}", defaultAD.IsDefaultAppDomain());
            Console.WriteLine("Base directory of this domain: {0}", defaultAD.BaseDirectory);
        } 
        #endregion

        #region List loaded assemblies 
        static void ListAllAssembliesInAppDomain()
        {
            // Get access to the app domain for the current thread.
            AppDomain defaultAD = AppDomain.CurrentDomain;

            // Now get all loaded assemblies in the default app domain. 
            var loadedAssemblies = from a in defaultAD.GetAssemblies() orderby a.GetName().Name select a;

            Console.WriteLine("***** Here are the assemblies loaded in {0} *****\n",
              defaultAD.FriendlyName);
            foreach (var a in loadedAssemblies)
            {
                Console.WriteLine("-> Name: {0}", a.GetName().Name);
                Console.WriteLine("-> Version: {0}\n", a.GetName().Version);
            }
        } 
        #endregion

    }
}

上面的代碼是我從“Andrew Troelsen”的“Pro C# 2010 and the .NET 4 Platform”一書中得到的。 在這里,當我運行此代碼時,控件永遠不會到達該行

            defaultAD.AssemblyLoad += (o, s) =>
                {
                    Console.WriteLine("{0} has been loaded!", s.LoadedAssembly.GetName().Name);
                };

為什么運行此代碼時未觸發此事件? 當控制到達這里?

由於多種原因,未到達此事件處理程序。 AppDomain.CurrentDomain 已加載開始執行 Main 方法所需的所有程序集。 所以你添加你的事件處理程序太晚了。 您需要添加一個特殊的靜態方法,.NET 框架會查找該方法並將其執行以運行您的應用程序初始化代碼,它稱為 AppInitialize,您將在那里綁定您的處理程序。 對 AppInitialize 進行一些挖掘。

此外,您的域不是唯一涉及的域。 肯定至少有一個其他共享應用程序域,所有 GAC 和完全信任的程序集都加載到其中。 此外,根據應用程序的配置方式以及其他程序集加載其依賴項的方式,可能還有其他應用程序域。 在 MSDN 上進行有關應用程序域主題的盡職調查。

事件不會觸發,因為當應用程序啟動時,所有引用的程序集都已加載(以防您沒有動態加載程序集)。

根據文檔(以及我所經歷的),該事件僅在使用Assembly.Load方法之一時觸發。

當運行時自動解析和加載程序集時,它不會觸發。

我也遇到了 AssemblyLoad 的問題。 我不得不使用以下設置對其進行調查:

1. 在 ASP.Net 應用程序啟動期間,在配置 DI 時,將事件處理程序添加到 AssemblyLoad 事件記錄所有加載的程序集和 AppDomain FirendlyName。
2. 之后,所有已經加載的程序集也被記錄下來。
3. 在其他地方的控制器構造函數中,再次記錄所有加載的程序集。
4. 所有依賴項都在 GAC 中。

結果:
所有日志都顯示相同的 AppDomain 名稱,但控制器日志顯示的加載程序集比 (2) 和 AssemblyLoad 事件處理程序 (1) 最初記錄的程序集加起來還要多。 所以它看起來不像是為所有加載的程序集觸發了 AssemblyLoad。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM