19

私は自分のプロジェクトに汎用リポジトリを持っています。 私は一般的なリポジトリ内だけでなく、私のコントローラのそれぞれ両方の私のデータベースの参照を持っている必要がありますが表示されない、次のコントローラスニペットStartup.csのテーブルごとに別々のAddScoped行がなくても、ASP.NETコアの汎用リポジトリ?

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); 
    } 

を考えてみましょう。

私はそれをリファクタリング:非常にすっきりと私が読んだものからASP.NET 5のベストプラクティスである

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); 
    } 

} 

。 しかし、私は私のブラウザでそのコントローラのルートにアクセスする場合、私は次のエラーが発生します。

InvalidOperationException: Unable to resolve service for type 'MyProject.Data.IGenericRepository`1[MyProject.Models.Lookup1]' while attempting to activate 'MyProject.Controllers.Lookup1. 

私はインターフェイスを使用するGenericRepositoryを注入されていないのです。

私のコードが例外をスローせずに実行されるように、私はConfigureServices方法で私のStartup.cs

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 

を私のテーブルの一人ひとりのためAddScopedの行を追加します。

私のデータベースには約100の単純なルックアップテーブルがあります。上記の100行のコードを見ると、正しく表示されません。

コピー&ペーストのような感じです。新しいモデルとコントローラをビューに追加して新しいテーブルを追加するたびに、私のコードはエラーを出すことなくコンパイルされます。しかし、プログラムを実行してそのビューに移動すると、私がStartup.csにAddScopedラインを追加するのを忘れた場合、コントローラがエラーを起こすことがあります。メンテナンス性にはあまり効果がありません。

私の質問:

  1. はそれが本当にベストプラクティスはStartup.csConfigureServices方法でそれぞれのservices.AddScoped、すべてのルックアップテーブルを持っていますか?

  2. これは一般的なリポジトリなので、100行のコピーとペーストの行を1行に書き込む方法はありませんか?

  3. 私のコードを使用してこれを行うベストプラクティス方法は何ですか?

+0

のリポジトリの依存関係を追加します'*としてパラメータ*:'パブリックLookup1Controller(IGenericRepository リポジトリ) '。したがって、* MVCはコントローラのコンストラクタ 'Lookup1Controller'を対応するパラメータで呼び出します。'新しいGenericRepository >()'を誰が作るべきですか?これを一度行うか、 'Index'アクションの呼び出しごとに行うべきでしょうか?したがって、 'services.AddTransient'、' services.AddScoped'、 'services.AddSingleton'、' services.AddInstance'の中から選択できます。 – Oleg

+0

基本的なCRUDシステムです。だからCreateがある。更新、削除メソッド私は省略した。 AddScopedを使用するのが標準的な方法です:http://wildermuth.com/2015/3/17/A_Look_at_ASP_NET_5_Part_3_-_EF7。より良い方法があれば、共有してください。 – devc2

答えて

39

ただ、非ジェネリック登録のオーバーロードを使用すると、あなたのインタフェースと実装の両方のopen generic typesを提供します(2つのTypeオブジェクトを渡す必要があるものを。):あなたは

services.AddScoped(typeof(IGenericRepository<>), typeof(GenericRepository<>)); 

をコントローラは、あなたが `IGenericRepositoryと` Lookup1Controller`のコンストラクタを使用して、特定のタイプ(クローズジェネリック型)

public HomeController(IGenericRepository<Lookup1> repository) 
{ 
    ... 
} 
+0

ありがとうございます。 1行のコードを変更すると動作します。 ASP.net 5アプリケーションのための良い練習であるかどうか、他の人が入力をしているかどうかを確認するか、またはalterantを提供する – devc2

+0

登録方法は、[Ninject](http://stackoverflow.com)のような他のDIコンテナと同じです。/a/10243699/1836935)または[Unity](https://msdn.microsoft.com/en-us/library/ff660936(v=pandp.20).aspx#Anchor_0)を参照してください。誰かがASPの組み込みコンテナを持った問題を知っているかどうかを見てみましょう.Net 5 –

+3

これは私には当てはまりません。このエラーが発生しました:失敗:Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware [0]未処理の例外が発生しました: 'SqlExpress.Helpers.LessonTagHelper'をアクティブにしようとしているときに、 'SqlExpress.Repository.Interfaces.IChatRepository'タイプのサービスを解決できません。 System.InvalidOperationException: 'SqlExpress.Helpers.LessonTagHelper'をアクティブにしようとしているときに、 'SqlExpress.Repository.Interfaces.IChatRepository'タイプのサービスを解決できません。 ... – Beetlejuice

関連する問題