ASP.NETMVCプロジェクトでベースコントローラーを使用することについて多くの人が話しているのを見てきました。私が見た典型的な例は、ロギングまたはおそらくCRUDスキャフォールディングのためにこれを行います。基本コントローラークラスの他の良い使用法は何ですか?
10 に答える
基本コントローラークラスの適切な使用法はありません。
今、私を聞いてください。
Asp.Net MVC、特にMVC 3には、すべてのコントローラーに機能を追加するためのより分離された方法を提供する多数の拡張性フックがあります。コントローラクラスは非常に重要であり、アプリケーションの中心であるため、それらを軽量で機敏に保ち、他のすべてのものと緩く結合することが非常に重要です。
ロギングインフラストラクチャはコンストラクターに属し、DIフレームワークを介して注入する必要があります。
CRUDスキャフォールディングは、コード生成またはカスタムModelMetadataプロバイダーによって処理される必要があります。
グローバル例外処理は、カスタムActionInvokerで処理する必要があります。
グローバルビューのデータと承認は、アクションフィルターで処理する必要があります。MVC3のグローバルアクションフィルターを使用するとさらに簡単になります。
定数は、ApplicationConstantsなどと呼ばれる別のクラス/ファイルに入れることができます。
ベースコントローラーは通常、MVCのさまざまな拡張性部分をすべて知らない経験の浅いMVC開発者によって使用されます。今私を誤解しないでください、私はすべての間違った理由でそれらを使用する人々を判断して協力していません。一般的な問題を解決するためのより多くのツールを提供するその単なる経験。
基本コントローラークラス以外の拡張性フックで解決できない問題は1つもないと私はほぼ確信しています。生産性に重大な理由があり、リスコフに違反しない限り、最も緊密な結合(継承)を採用しないでください。public ILogger Logger { get; set; }
アプリケーションにはるかに重要な影響を与える密結合を導入するよりも、コントローラー全体でプロパティを20回入力するのに1秒未満かかるほうがはるかに望ましいです。
userIdやマルチテナントキーのようなものでも、ベースコントローラーの代わりにControllerFactoryに入れることができます。基本コントローラークラスの結合コストは、それだけの価値はありません。
承認にはベースコントローラーを使用するのが好きです。
各アクションを「Authorize」属性で装飾する代わりに、ベースコントローラーで承認を行います。許可されたアクションのリストは、ログインしたユーザーのデータベースから取得されます。
承認の詳細については、以下のリンクをお読みください。 カスタムコントローラファクトリで一般的な認証を行うための良い習慣はありますか?
セッションやアプリケーションデータなどにアクセスするために使用します。
また、アプリ名などを保持するアプリケーションオブジェクトがあり、基本クラスからアクセスします。
本質的に私は私が頻繁に繰り返すことのためにそれを使用します
ああ、私はそれをビジネスロジックやデータベースアクセスに使用しないことを言及する必要があります。定数は基本クラスにとってもかなり良い賭けだと思います。
私は自分のプロジェクトの多くでベースコントローラーを使用していて、素晴らしい仕事をしました。私は主に
- 例外ログ
- 通知(成功、エラー、追加..)
- HTTP404エラー処理の呼び出し
私の経験から、ベースコントローラーに配置したいロジックのほとんどは、理想的にはアクションフィルターに入ります。アクションフィルターは定数でのみ初期化できるため、場合によってはそれができないことがあります。場合によっては、システム内のすべてのアクションメソッドに適用するアクションが必要です。その場合、新しいactionFilter属性ですべてのアクションメソッドに注釈を付けるよりも、ロジックをベースに配置する方が理にかなっている場合があります。
また、サービスを参照するプロパティ(コントローラーから切り離されている)をベースに配置して、アクセスを容易にし、一貫して初期化できるようにすることも役立ちます。
私がしたことは、汎用コントローラーの基本クラスを使用して以下を処理することでした。
- 基本クラスがCreate / Edit / Deleteを処理するように、コンストラクターパラメーターとしてオブジェクト
BaseCRUDController<Key,Model>
を必要とするものを作成しました。そして、カスタムの状況で処理するために仮想モードで確実にICRUDService<TModel>
- Save / Update / Delete / Find / ResetChache / ...の
ICRUDService<TModel>
ようなメソッドがあり、作成するリポジトリごとに実装して、さらに機能を追加できるようにします。 - この構造を使用して、PagedList / AutoComplete / ResetCache / IncOrder&DecOrder(モデルがIOrderableの場合)などの一般的な機能を追加できます。
エラー/通知メッセージの処理:
@TempData["MHError"]
コードを含むレイアウトの一部と、次のようなベースコントローラーのプロパティpublic Notification Error {set {TempData ["MHError"] = value; } get {return(Notification)TempData.Peek( "MHError"); }}
この抽象クラスを使用すると、毎回記述したり、コードジェネレーターで作成したりする必要のあるメソッドを簡単に処理できました。しかし、このアプローチには弱点もあります。
BaseControllerは次の2つの目的で使用します。
- すべてのコントローラーに適用する必要がある属性。
- リダイレクトURLがローカルURLであることを確認することにより、オープンリダイレクト攻撃から保護するリダイレクトのオーバーライド。これにより、リダイレクトを呼び出すすべてのコントローラーが保護されます。
現在、 i18Nライブラリを使用した国際化のためにベースコントローラを使用しています。これは、コントローラー内の任意の文字列をローカライズするために使用できるメソッドを提供します。
フィルタはスレッドセーフではありません。データベースへのアクセスと依存性注入の条件です。データベース接続は、使用時に他のスレッドによって閉じられる可能性があります。
ベースコントローラーを使用しました:
.User
独自のカスタムプロパティを持つ必要がある独自のUserオブジェクトを使用するため、プロパティをオーバーライドします。- グローバル
OnActionExecuted
ロジックを追加し、いくつかのグローバルアクションフィルターを追加します