25

最近は、サード パーティの MVC プラグインをホストできる ASP.NET MVC アプリケーションの作成に注力しています。理想的には、これらのプラグインの開発は次のルールに従います。

  1. プラグインは、標準の MVC プロジェクトで開発でき、ASP.NET MVC フレームワークの既存のインフラストラクチャをすべて使用できます。
  2. プラグイン MVC プロジェクトのコンパイルとホスト MVC アプリケーションへの組み込みの複雑さは深刻ではありません。
  3. MVC アプリケーションの通常の開発フローへの変更は最小限に抑えられます。

いくつかの調査の後、これを達成するための次のアプローチを思いつきました。それぞれに長所と短所があります。

アプローチ 1 - メイン MVC AppDomain にロードされた MVC プラグイン アセンブリ

ワークフロー

  • 別の MVC プロジェクト内でプラグインを開発します。
  • アセンブリをコンパイルし、ホスト プロジェクト内のPreApplicationStartMethodAttributeMEF 、または基本的なアセンブリ参照 (可能な場合)を介して、アセンブリとすべての依存関係をホスト アプリケーションに読み込みます。
  • プラグインがホスト内でとして扱われるように、ルートをプラグイン コントローラにマップしAreaます。
  • プラグイン ビューを正しいエリア フォルダーに配置します。レイアウト ファイルは、レイアウト パスがアプリケーションのルートではなくエリア ベースの場所を指すように変更する必要があります (開発 MVC プロジェクトの場合)。
  • プラグインに対する要求が届くと、ASP.NET は既存の領域機能を使用して要求を正しいコントローラーにルーティングし、ビュー ファイルの正しい場所を調べます。

利点

  1. コントローラーがホスト MVC アプリケーション アセンブリに埋め込まれているかのようにシームレスに動作します。
  2. PreApplicationStartMethodAttributeアプリケーションの開始前 ( 、プロジェクト参照) およびアプリケーションの開始後 ( MEF )に、アセンブリをホスト アプリケーション ドメインに簡単に含めることができます。

短所

  1. サンドボックスなし - コントローラーはホストと同じ信頼レベルになります。

結論

これは最も簡単な方法ですが、安全性も最も低くなります。これらのプラグインはホスト アプリケーションと同じ信頼レベルを持つため、信頼されていない開発者がプラグインを作成することを許可する可能性を本質的に排除します (つまり、ホスト アプリケーションが などのメソッドを実行できる場合System.IO.File.Delete、プラグインも実行できます)。

アプローチ 2 - MAF を介して独自の AppDomain で実行される MVC プラグイン アセンブリ

このアプローチは、独自にサンドボックス化し、ライブラリAppDomainsを介してホストが使用できる MVC プラグインを作成できるようにすることを目的としています。System.Addin

構造

  1. 処理中の URL がプラグインを対象としているかどうかを判断するルートがホストに設定されます。などのパターンが考えられます。example.com/p/{plugin}/{controller}/{action}/{id}

  2. 上記のパターンを持つすべてのルートは、モジュール ルーティング アクションを持つホスト コントローラーにマップされます。そのアクションは、特定のルートを調べて、{plugin}セグメントに基づいてリクエストを処理する適切なプラグインを決定します。

  3. プラグイン ビューは、プラグイン コントローラーへのゲートウェイとして機能するレシーバー/センダー オブジェクトです。ホストからを受け取り、を返すAcceptRequestというメソッドがあります。RequestContextActionResult

  4. プラグイン パイプラインには、パイプラインの分離境界を越えてシリアル化RequestContextおよび送信できるアダプターが含まれています。ActionResult

実行の流れ

  1. プラグインのルートが照合され、プラグイン ルーティング コントローラーが呼び出されます。

  2. コントローラーは、必要なプラグインを独自のプラグインにロードし、AcceptRequestAppDomainを呼び出して(パイプライン経由でシリアル化されます) を通過します。RequestContext

  3. AcceptRequestはコンテキストを受け取り、その要求に基づいて実行する適切なコントローラーを決定します (カスタム コントローラー ファクトリを使用)。

  4. コントローラがリクエストの実行を完了すると、レシーバ オブジェクトに が返さActionResultれ、レシーバ オブジェクトはそれをActionResult(これもパイプライン経由でシリアル化されて) ホストに戻しますAppDomain

  5. 最初にAcceptRequestActionResultを呼び出したコントローラーは、要求自体を処理したかのように、ホスト MVC 実行パイプラインに を返すことができます。その後、必要に応じてプラグインAppDomainをアンロードできます。

利点

プラグインは でサンドボックス化されるAppDomainため、ホストに適した任意の権限セットを使用できます。

短所

  • シリアル化RequestContextおよびActionResult.
  • 分離された 内の他の ASP.NET MVC 機能が壊れる可能性がありますAppDomain

結論

このアプローチは紙の上では良さそうに思えますが、オブジェクトRequestContextActionResultオブジェクトをシリアル化し、MVC コントローラーを分離して実行することが可能/実行可能かどうかはわかりません。

質問

コードが信頼できる開発者によって作成されている場合は、最初の方法で問題ありません。すべてのホスト ビュー ファイルまたは web.config ファイルを削除するつもりはないことはわかっています。しかし最終的に、サード パーティの開発者に MVC アプリ用のプラグインを作成してもらいたい場合は、サード パーティのコードをサンドボックス化できる必要があります。

私のすべての調査によると、System.Addin単純な API ベースのクラス ライブラリを使用している場合、このライブラリを使用すると、ホスト/プラグイン環境を簡単に実装できます。しかし、MVC が関係する場合、これを行うのは容易ではないようです。

私が持っているいくつかの質問は次のとおりです。

  1. ここで概説した 2 番目のアプローチは実行可能ですか?
  2. これを行うより良い方法はありますか?
  3. 将来、MVC プラグインの分離を実現するためのより簡単な方法はありますか?
4

2 に答える 2

0

IMHO System.AddIn は、あなたがやろうとしていることに対して少しやり過ぎです。

System.Security.Permissions名前空間に精通していますか? そうでない場合は、FileIOPermissionを確認できます。おそらく、.NET のコード アクセス セキュリティメカニズムを使用して (そして拡張しないのは当然)、拡張可能なシステムをサンドボックス化することができます。

于 2012-05-21T15:45:51.523 に答える