1
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);
                };

为什么在我运行此代码时不会触发此事件?当控制到达这里?

4

4 回答 4

2

由于多种原因,无法访问此事件处理程序。AppDomain.CurrentDomain 已加载开始执行 Main 方法所需的所有程序集。因此,您添加事件处理程序为时已晚。您需要添加一个特殊的静态方法,.NET 框架会查找并将执行以运行您的应用程序初始化代码,它称为 AppInitialize 并且您将在那里绑定您的处理程序。对 AppInitialize 进行一些挖掘。

此外,您的域不是唯一涉及的域。肯定至少有一个其他共享应用程序域,所有 GAC 和完全受信任的程序集都被加载到其中。另外,根据应用程序的配置方式以及其他程序集如何加载它们的依赖项,可能还有其他应用程序域。在 MSDN 上就应用程序域的主题进行尽职调查。

于 2017-03-11T18:46:58.577 回答
1

事件不会触发,因为当应用程序启动时,所有引用的程序集都已加载(以防您没有动态加载程序集)。

于 2013-02-15T10:48:07.070 回答
1

从文档(以及我所经历的)来看,该事件仅在使用其中一种Assembly.Load方法时才会触发。

当运行时自动解析并加载程序集时,它不会触发。

于 2013-02-15T10:53:48.167 回答
0

我也遇到了 AssemblyLoad 的问题。我必须使用以下设置对其进行调查:

1. 在 ASP.Net 应用程序启动期间,在配置 DI 时,将事件处理程序添加到 AssemblyLoad 事件中,记录所有加载的程序集和 AppDomain FirendlyName。
2. 之后,所有已加载的程序集也被记录下来。
3. 在其他地方的控制器构造函数中,所有加载的程序集都被再次记录。
4. 所有依赖项都在 GAC 中。

结果:
所有日志都显示相同的 AppDomain 名称,但控制器日志显示的加载程序集比最初由 (2) 和 AssemblyLoad 事件处理程序 (1) 记录的组合更多。因此,看起来甚至没有为所有加载的程序集触发 AssemblyLoad。

于 2020-01-09T08:29:48.770 回答