未在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中激发AssemblyLoad事件

由于多种原因,无法访问此事件处理程序。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似乎都没有被激发。