0

堅牢である必要があるオートメーション スケジューラ用のプラグイン アーキテクチャを作成しているので、ASP.NET/IIS スタイルの AppDomains を実行しようとしています。彼ら。

ApplicationBaseConfigurationFile、およびを に設定ShadowCopyFilesしていAppDomainSetupます。

自動化スケジューラには、プラグインごとにロードする共通のアセンブリが 1 つあります。このアセンブリは、プラグインのメイン アセンブリのロード、キャッチされていない例外のキャッチ、およびログ記録を処理します。私が特定したこのアプローチには、いくつかの弱点があります。

  • プラグインが保存されている場所に設定ApplicationBaseすると、共通アセンブリ (別のパスにある) の依存関係は解決されなくなります。イベントをフックすることでこれをハッキングして機能させましたAssemblyResolveが、それは他の問題につながります。

  • 共通アセンブリとプラグインの両方が、同じ名前のアセンブリの独自のコピーを参照している可能性があります (それぞれが異なるバージョンを持つ可能性があります)。または、同じ名前で内容がまったく異なるアセンブリの可能性もあります。をオーバーライドAssemblyResolveすると、プラグインのコピーが常に最初にロードされます。

  • これについてはあまり心配していませんが、セキュリティの観点から、プラグインがスケジューラの依存関係をオーバーライドして、悪意のあることを実行したり、共通アセンブリに反映して内部に侵入したりする可能性があることを認識しています。

したがって、おそらくこれを適切に行う唯一の方法は、単にそれを行わないことであると判断しました。強制的に完全に分離し、AppDomain にアセンブリを読み込まないでください。これについての最善の方法が何であるか、またはそれが最善のアプローチであるかどうかさえ、私にはよくわかりません。

どう思いますか?

4

1 に答える 1

0

これがあなたの質問に正確に答えるかどうかはわかりませんが、独立した子 AppDomains と共有 DLL のフォルダーを持つアプリケーションで同様のセットアップを行い、AssemblyResolve を使用せずに成功しました。

ファイル構造は次のとおりです。

[PathToApplication]\OurApplication.exe
[PathToApplication]\AddIns\[SharedAssemblies]\*.dll
[PathToApplication]\AddIns\[FirstAddIn]\*.dll
[PathToApplication]\AddIns\[SecondAddIn]\*.dll

角括弧内の部分は実際のパスに置き換えられます。

この場合、共有アセンブリはメインの AppDomain によっても読み込まれるため、次のようにメインで設定しApp.configます。

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <probing privatePath="AddIns\[SharedAssemblies]" />
  </assemblyBinding>
</runtime>

共有アセンブリがメインの実行可能ファイルと一緒に存在しないことを確認してください。そうしないと、代わりにそこから読み込まれます。これにより、すべての AppDomain 間でメモリ内で共有されている DLL がサイレント モードで停止します。

次に、アドインの AppDomain ごとに、ベース パスがアドインのフォルダーと共有フォルダーの両方の上にあるフォルダーになるように構成し、プライベート ビンのパスを設定して、正しいサブフォルダーを正しい順序で検索するようにしました。

var basePath = @"[PathToApplication]\AddIns";

var configFile = Path.Combine(
        basePath, 
        addInFolder, 
        addInAssemblyName + ".dll.config");

var binPaths = new [] { "[SharedAssemblyFolder]", addInFolder };

setup = new AppDomainSetup
{
    ApplicationBase = basePath,
    ConfigurationFile = configFile,
    LoaderOptimization = LoaderOptimization.MultiDomain,
    PrivateBinPath = string.Join(";", binPaths),
    PrivateBinPathProbe = string.Empty,
};

この方法では、常に最初に共有フォルダーが検索されるため、アドインが同じ名前の独自の DLL を提供しても無視されます。

これをアプリケーション エントリ ポイントに設定して実行し[System.LoaderOptimization(LoaderOptimization.MultiDomain)]、DLL が実際にメモリ内で共有されていることを確認しました (少し間違えて、これが発生するのを黙って停止するのは簡単です)。

これが何らかの形で役立つことを願っています。

于 2013-03-20T10:16:32.527 に答える