未在AppDomain中激发AssemblyLoad事件
本文关键字:AssemblyLoad 事件 AppDomain 未在 | 更新日期: 2023-09-27 17:59:19
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
}
}
上面的代码是我从AndrewTroelsen的"ProC#2010和.NET4平台"一书中得到的。在这里,当我运行这个代码时,控制永远不会到达行
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似乎都没有被激发。