Startup.csでテーブルごとに個別のAddScoped行を持たずにASP.NET Coreで一般的なリポジトリ?
質問
私のプロジェクトでは、一般的なリポジトリを持っています。 次のようなコントローラのスニペットを考えてみましょう。
public class Lookup1Controller : Controller
{
readonly MyDbContext _db;
public Lookup1Controller(MyDbContext dataContext)
{
_db = dataContext;
}
public async Task<IActionResult> Index()
{
IGenericRepository<Lookup1> _repository = new GenericRepository<Lookup1>(_db);
var lookup1s = await _repository.SelectAll();
return View(lookup1s);
}
Genericリポジトリと各コントローラの両方にDatabaseの参照を持つ必要はないように思います。
私はそれをリファクタリングします。
public class Lookup1Controller : Controller
{
private IGenericRepository<Lookup1> _repository;
public Lookup1Controller(IGenericRepository<Lookup1> repository)
{
_repository = repository;
}
public async Task<IActionResult> Index()
{
var lookup1s = await _repository.SelectAll();
return View(lookup1s);
}
}
の方がずっときれいで、私が読んだ限りではASP.NET 5のベストプラクティスです。 しかし、ブラウザでそのコントローラルートにアクセスすると、次のエラーが発生します。
InvalidOperationException: Unable to resolve service for type 'MyProject.Data.IGenericRepository`1[MyProject.Models.Lookup1]' while attempting to activate 'MyProject.Controllers.Lookup1.
というのも、GenericRepositoryをインジェクションしていないので、インターフェースを利用することができません。
私は自分の
Startup.cs
に
AddScoped
の行で、それぞれのテーブルに対して
ConfigureServices
メソッドで
services.AddScoped<IGenericRepository<Lookup1>,GenericRepository<Lookup1>> ();
services.AddScoped<IGenericRepository<Lookup2>,GenericRepository<Lookup2>> ();
services.AddScoped<IGenericRepository<Lookup3>,GenericRepository<Lookup3>> ();
services.AddScoped<IGenericRepository<Lookup4>,GenericRepository<Lookup4>> ();
etc
で、私のコードが例外を投げずに実行されるようにします。
しかし、私のデータベースには約100の単純なルックアップテーブルがあります。上記の100行のコードを見たとき、それは正しく見えません。
それはコピーアンドペーストコードのように感じます。新しいテーブルを追加するたびに、新しいモデルとビューを持つコントローラを追加することで、私のコードはエラーを出さずにコンパイルされます。しかし、プログラムを実行し、そのビューに移動すると、AddScoped 行を
Startup.cs
. メンテナンス性にはあまりよくありません。
私の質問です。
-
の各ルックアップテーブルに services.AddScoped を設定することは、本当にベストプラクティスなのでしょうか?
ConfigureServices
メソッドのStartup.cs
? -
汎用リポジトリなので、100行のコピペを1行で書く方法はないのでしょうか?
-
そうでない場合、私のコードを使用してこれを行うためのベストプラクティスの方法は何ですか?
どのように解決するのですか?
一般的でない登録のオーバーロードを使用すればよいのです(2つの
Type
オブジェクトを渡す必要があります)。そして
オープンジェネリックタイプ
を提供します。
services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>));
コントローラで、特定のタイプ(クローズドジェネリックタイプ)のリポジトリに対する依存関係を追加します。
public HomeController(IGenericRepository<Lookup1> repository)
{
...
}
関連
-
[解決済み] KotlinのPair用コンパレータ
-
[解決済み】Scala。抽象型とジェネリックス
-
[解決済み] Kotlinのジェネリックにおける "*"と "Any "の違いについて
-
[解決済み] なぜ例がコンパイルできないのか、別名、(co-, contra-, in-)分散はどのように機能するのか?
-
[解決済み] KotlinでGsonを使ったTypeToken + ジェネリックの使い方
-
[解決済み] kotlinのoutキーワードとは
-
[解決済み] オプションの汎用タイプ
-
[解決済み] Kotlinの汎用拡張クラスとインターフェイスの実装
-
[解決済み] MIN および MAX マクロの Swift 対応版
-
[解決済み] Kotlinでジェネリックパラメータクラスを取得する方法
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Kotlinのreifiedキーワードはどのように機能するのですか?
-
[解決済み] Kotlinのジェネリックにおける "*"と "Any "の違いについて
-
[解決済み] なぜ例がコンパイルできないのか、別名、(co-, contra-, in-)分散はどのように機能するのか?
-
[解決済み] KotlinでGsonを使ったTypeToken + ジェネリックの使い方
-
[解決済み] kotlinのoutキーワードとは
-
[解決済み] .NETの「オープンジェネリック型」とは何ですか?重複
-
[解決済み] オプションの汎用タイプ
-
[解決済み] Kotlinの汎用拡張クラスとインターフェイスの実装
-
[解決済み] MIN および MAX マクロの Swift 対応版
-
[解決済み] Kotlinでジェネリックパラメータクラスを取得する方法