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 アセンブリと完全に信頼されたアセンブリが読み込まれる、少なくとも 1 つの他の共有アプリ ドメインが確実に存在します。さらに、アプリケーションの構成方法と他のアセンブリが依存関係を読み込む方法に基づいて、他のアプリ ドメインが存在する可能性があります。アプリケーション ドメインのトピックについて、MSDN で十分な調査を行ってください。

于 2017-03-11T18:46:58.577 に答える
1

アプリケーションの起動時に、参照されているすべてのアセンブリがすでにロードされているため、イベントは発生しません(アセンブリを動的にロードしていない場合)。

于 2013-02-15T10:48:07.070 に答える
1

ドキュメント(および私が経験したこと)から、イベントはAssembly.Loadメソッドの1つが使用された場合にのみ発生します。

ランタイムがアセンブリを自動的に解決して読み込むときは起動しません。

于 2013-02-15T10:53:48.167 に答える