13

共通の機能セット (および対応する URL、ルート、コントローラー、アクション、およびビュー) を持つ約 10 の ASP.NET MVC サイトを構築しています。また、これらのサイトはすべて、ドメイン オブジェクト (ユーザー、会社など) の基本セットと、それらのオブジェクトの基本属性 (名前、住所など) を共有します。

しかし、各サイトも高度にカスタマイズされ、ベースから拡張されます。たとえば、大規模な上場企業向けのサイトには、Company ドメイン オブジェクトに「子会社」および「株式シンボル」フィールドがあり、新興企業向けのサイトには「ベンチャー企業」および「資金調達」属性があります。ルック アンド フィールも大幅に異なりますが、HTML は可能な限り一貫性を保つように努めています (追加のドメイン オブジェクト属性用に追加のフォーム フィールドをモジュロ化するなど)。また、画像を控えめにオーバーライドすることで、たとえば、サイト間で同じボタン グラフィックを再利用できるようにします。

とにかく、アプリごとの属性を追加したり、アプリ間で UI を変更したりする自由を制限することなく、できるだけ多くのコードとできるだけ多くのテストを再利用できるように、要素を分解して設計する最善の方法を見つけようとしています。

私は、UI が少し異なり、データ モデルが多かれ少なかれ、StackOverflow/SuperUser/ServerFault (または MSDN/TechNet) に見られるような、カスタマイズが制限されたマルチテナンシーを処理する方法に精通しています。同一。しかし、モデルと UI が大きく異なる (ただし、共通のベースから継承している) 場合、どのように進めればよいかわかりません。

おそらく、各サイトを別々のアプリドメインで実行し、別々のデータベースでホストすることになるため、運用上の問題についてはあまり心配していません. 長期的なコード メンテナンス コストの削減、アジリティの向上 (派生アプリを壊すことなく新しい機能をベースに簡単に追加できるなど)、そして 2 番目のコードを構築する際の短期的な開発/テスト コスト削減の実現について心配しています。 3 番目、4 番目などのサイト。

高レベルのガイダンスと提案の両方を探していますが、最新の ASP.NET MVC プラクティスを使用してそのガイダンスを実現する方法についての具体的な提案も求めています。

これは非常に一般的な質問であることは承知していますが、まず、高レベルのガイダンスと、ASP.NET MVC でそのガイダンスを適用する方法に関する具体的なヒントとコツの両方を探しています。たとえば、次のようなものがあります。

  • Visual Studio プロジェクト間でベース/派生を分割する推奨事項
  • フォークを回避するためのソース管理のヒント
  • データベース スキーマのヒント (FWIW、私たちのデータベースはすべて小さいです。テーブルごとに 10,000 行未満なので、DB のパフォーマンスよりも開発/テストのコストの方が問題です)
  • コントローラー/ビュー/などの再利用に関するヒント。「基本」モデル属性に対応します。特に、基本属性と派生属性が混在する「新規顧客」フォームなどの UI を再利用します。

このようなマルチテナント アプリを設計する方法について、誰か良いアドバイスはありますか?

4

4 に答える 4

11

これが私たちが行っていることで、現在約 8 つのサイトでうまく機能しています。

  • コントローラー、ViewModel、HttpApplication、ルートなどのコア MVC プロジェクトを定義します。これにより、DLL にコンパイルされ、サイトの大部分が危険にさらされます。

  • サイトのデフォルト ビュー、スクリプト、画像などの基本セットを作成します。これらは、個々のサイトのデフォルトとしてサーバーされます。

  • クライアントごとに、別の dll にコンパイルするプロジェクトで必要なカスタム コントローラー、ルートなどを作成します。

  • また、クライアントごとに、使用するビュー、スクリプト、画像を再作成します。

上記の手順を一緒に機能させるには、少しのりを書く必要があります。最初の接着剤は、カスタム ビュー エンジンです。標準のビュー エンジンをカスタマイズして、最初にクライアント固有のフォルダーでビューを検索し、次に既定のフォルダーでビューを検索する必要があります。これにより、クライアントごとにデフォルトのレイアウトを簡単にオーバーライドできます。

すべてを機能させる 2 つ目の方法は、コア アプリケーションに、クライアント固有のアセンブリからルートやコントローラーなどを読み込ませることです。これを行うために、Managed Extensibility Framework (MEF) を使用して単一の Register メソッドを公開します。クライアント アセンブリ コードでこのメソッドを呼び出すと、ルートとその他のクライアント固有のニーズが登録されます。

これは、サイトのフォルダー構造がどのように見えるかの一般的なビューです。SiteContent のビューが最初にチェックされます。

  - AppContent
  - AppContent/Static
  - AppContent/Static/Images
  - AppContent/Static/Scripts
  - AppContent/Static/Styles
  - AppContent/Views
  - AppContent/Views/Shared

  - SiteContent
  - SiteContent/Static
  - SiteContent/Static/Images
  - SiteContent/Static/Scripts
  - SiteContent/Static/Styles
  - SiteContent/Views
  - SiteContent/Views/Shared

  - web.config
  - Global.asax

ビューで使用する SiteImage や AppImage などのヘルパーがあります。また、各クライアント サイトでマスター ページに特定の名前を使用するようにしています。これは、AppContent の既定値では決して定義していません。

これは大まかな概要であることは承知していますが、現時点では十分に機能しています。

于 2010-05-10T18:30:32.267 に答える
2

私は現在、顧客がオンラインで製品を申請できるようにすることに焦点を当てている同様のタイプの「スイート」プロジェクトに携わっていますが、収集する情報については非常に類似した要件があり、唯一の違いは製品固有の情報またはわずかなものです。さまざまな法的要件。

私たちが試みた1つのことは、それ自体で再利用可能なページ(モデル、ビュー、コントローラーの組み合わせ)を作成することです。これにより、どのアプリケーションもそのページを使用して情報をキャプチャできますが、次のページにリダイレクトできます。これは、タイプによって異なる場合があります。製品が申請されています。これを実現するために、基本的にすべての必要なコントローラーロジック(アクションフィルターが適用されたアクションメソッドを含む)を含むテンプレートメソッドパターンの形式で抽象ベースコントローラーを使用していますが、抽象メソッドを使用して、リダイレクトなどの特定の処理を実行します。プロセスの次のページ。これは、特定のアプリケーションページフローで使用されるコントローラーの具体的な実装には、フローの次のページに対応するRedirectToActionResultを返すメソッドが1つだけ含まれている可能性があることを意味します。

検証ロジックや状態永続化ロジックなど、一般的な機能を含むベースモデルオブジェクトもあります。

アプリケーションプロセス中にキャプチャされたデータは、xmlシリアル化モデルオブジェクトとしてデータベースに保持されます。アプリケーションが完了すると、バックエンド運用スタッフがアプリケーションの処理に使用するシステムに任意の形式で出力され、抽出および逆シリアル化できます。

これは、トップレベルの抽象クラス、インターフェイス、ユーティリティクラス、およびhtmlヘルパー、アクションフィルターなどを含むベースdllで構成されるプロジェクト構造があることを意味します。次に、の具体的な実装を含むmvcプロジェクトがあります。ベースコントローラー、モデルなど、およびビューとマスターページ。

最も難しいのはビューを共有することであり、これはまだ適切にソートされていないと思います。エリアを含むMVC2.0では、これはそれほど問題にはならないと思いますが、まだうまくプレイできていません。(2.0に関するScott Guの投稿を参照してください:http://weblogs.asp.net/scottgu/archive/2009/07/31/asp-net-mvc-v2-preview-1-released.aspx)動作するように見えるPOCの1つは、基本MVCプロジェクトに共通のビューを含め、デフォルトのビューエンジンを拡張して、レンダリングするビューを探すときにWebサーバー上でそのプロジェクトを検索します(これは非常に簡単です)。ただし、エリアははるかに優れたソリューションです。

ソース管理に関しては、svnを使用しており、ブランチについて心配するのは合理的だと思います。これはまだ対処しなければならないことではありませんが、分岐とマージのプロセスの負担が大幅に軽減されるように思われるため、おそらくgitを使用する予定です。

これが大いに役立つかどうかはわかりませんが、抽象コントローラーとモデルを念頭に置いて、HTMLヘルパーと部分ビューを使用して同様の機能をグループ化する方法を確認することを強くお勧めします。

于 2009-09-30T11:04:24.593 に答える
1

これを行う 1 つの方法は、ソース管理システムで分岐を使用することです。

main ブランチは共通機能用です。これで、カスタマイズ用のブランチが作成され、変更をカスタマイズにマージしたり、メイン ブランチに戻したりすることができます。

于 2009-10-30T21:44:36.920 に答える
1

Mike Hadlowは、これを達成する方法について詳しく説明しています。

http://mikehadlow.blogspot.com/2008/11/multi-tenancy-part-1-strategy.html

于 2009-09-30T03:45:33.503 に答える