2013-02-15 54 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進行關於應用程序域主題的盡職調查。