1

頻繁に変更されるソフトウェアのプラグインを作成しました。メイン ソフトウェアのすべての新しいバージョンでプラグインを動作させたい。そのため、リフレクションを介してプラグインのメイン オブジェクトを作成する前に、プラグインの依存関係 (メイン ソフトウェアの実行可能ファイル) をロードします。

ただし、これは常に機能するとは限りません。タイミングの問題があります。DLL が (完全に) ロードされないことがありますが、メイン オブジェクトを作成するコードは実行されます。これにより、依存関係が欠落しているという例外がスローされます。

オブジェクトを作成する前に DLL が完全にロードされるのを待つにはどうすればよいですか?

class PluginStarter
    {
        private MainPluginObject mainPluginObject = null;

        public PluginStarter()
        {
            AppDomain.CurrentDomain.AssemblyResolve += (sender, eventArgs) =>
            {
                var fullAssemblyName = new AssemblyName(eventArgs.Name);              

                if (fullAssemblyName.Name.Equals("MainSoftware"))
                {
                    var found = Assembly.LoadFile(Path.Combine(Environment.CurrentDirectory, AppDomain.CurrentDomain.FriendlyName));
                    return found;
                }
                else
                {
                    return null;
                }
            };

            Initialize();
        }

        private void Initialize() 
        {
            mainPluginObject = new MainPluginObject();
        }

        public void ShowForm()
        {
            mainPluginObject.ShowForm();
        }

        public void Dispose()
        {
            mainPluginObject.Dispose();
        }
    }

Initialize()メソッドのインライン化を無効にする[MethodImpl(MethodImplOptions.NoInlining)]とすぐに、それが機能します。ここでインラインを削除することは正しい解決策ですか? AssemblyDLL のロード ステータスを通知するイベントがない場合、他に何ができますか?

4

1 に答える 1

1

メソッドがインライン化されている場合、dll が必要になるため、PluginStarter コンストラクターが呼び出される前(メソッドがコンパイルされるとき)、特に AssemblyResolve イベントが初期化される前に読み込まれます。

したがって、Initialize がインライン化されていないことを確認するか、AssemblyResolve コードを静的コンストラクターに配置する必要があります。

静的コンストラクターを使用すると、作成される PluginStarter オブジェクトの数に関係なく 1 つのイベントのみが作成されるため、おそらくクリーンになります。

于 2013-08-06T18:10:24.610 に答える