2013-02-15 67 views
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和.NET 4 Platform”一书中获得的。 在这里,当我运行这段代码,控制永远不会到达行AssemblyHoad事件未在AppDomain中触发

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

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

回答

1

从文档(以及我所经历的)中,仅当使用Assembly.Load方法之一时才会触发事件。

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

+0

[docs](https://msdn.microsoft.com/en-us/library/system.appdomain.assemblyload(v = vs.110).aspx)在哪里说的?至少现在的版本只是说“当程序集加载时发生。” – 2017-09-14 12:41:50

1

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

1

由于以下原因未能达到此事件处理程序。 AppDomain.CurrentDomain加载了开始执行Main方法所需的所有程序集。所以你太迟加入你的事件处理程序了。您需要添加一个特殊的静态方法,.NET框架将查找并执行以运行您的应用程序init代码,它被称为AppInitialize,并且您将绑定您的处理程序。做一些挖掘AppInitialize。

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