[英]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.