AppLmain中未触发AssemblyLoad事件

时间:2013-02-15 10:42:51

标签: c# .net visual-studio-2010

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 C&2010和.NET 4平台”的书,来自'Andrew Troelsen'。 在这里运行此代码时,控件永远不会到达

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

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

4 个答案:

答案 0 :(得分:1)

事件不会触发,因为在应用程序启动时,所有引用的程序集都已加载(如果您尚未动态加载程序集)。

答案 1 :(得分:1)

由于多种原因,未达到此事件处理程序。 AppDomain.CurrentDomain已加载开始执行Main方法所需的所有程序集。所以你要添加你的事件处理程序太晚了。您需要添加一个.NET框架查找的特殊静态方法,并执行该方法来运行您的应用程序初始化代码,它被称为AppInitialize,您可以在那里绑定您的处理程序。在AppInitialize上做一些挖掘。

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

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

结果:
所有日志均显示相同的AppDomain名称,但控制器日志显示的已加载程序集比最初由(2)和AssemblyLoad事件处理程序(1)记录的总和要多。因此,对于所有已加载的程序集,甚至都不会触发AssemblyLoad。