1

以前は比較的使い慣れたものは、もはやそうではありません。私が検索した数十回のうち、私はほとんどのプロジェクト構造で普及している以外のものは信じられない、この状況に対する答えを見つけることはめったにありません。同じAsp.Net Core 2ソリューションでクラスライブラリプロジェクトにDbContextを注入

私は、標準のCore 2.0 Webアプリケーションを用意しています。ここでは、簡単のため、Infrastructureプロジェクトと単体テストプロジェクトを用意しています。私は、テストプロジェクトがasp.netを実行していないので、テストシナリオをどのように達成するかを知っており、それを達成するための素晴らしいビデオチュートリアルを持っています。

インフラストラクチャプロジェクトのDbContextへのアクセスに問題があります。 (.NETコアクラスライブラリ)

DbContextはい

var connString = Configuration.GetSection("ApplicationConfiguration:ConnectionStrings:DefaultConnection").Value; 
     services.AddDbContext<ApplicationDbContext>(options => 
      options.UseSqlServer(connString)); 

とコントローラで、私はそれを

private ApplicationDbContext _context; 
private IConfiguration Configuration { get; set; } 

public HomeController(IConfiguration configuration, ApplicationDbContext context) 
{ 
    _context = context; 
    Configuration = configuration; 
} 

public IActionResult Index() 
{ 
    // gets users from the DI injected context in the controller 
    var users = _context.AppUsers.ToList(); 

    // if GetUsers is defined statically, this doesn't work because the injected context is always null 
    //var diUsers = DatabaseService.GetUsers(): 

    // making it non-static and newing it up works, but defeats the purpose because you are passing the context, asp.net is not injecting it 
    var ds = new DatabaseService(_context); 
    var diUsers = ds.GetUsers(); 

    var svm = SettingsViewModel(); 

    return View(svm); 
} 

DatabaseService

private ApplicationDbContext _context; 
//this is the constructor for DatabaseService class 
public DatabaseService(ApplicationDbContext context) 
{ 
    _context = context; 
} 

public List<ApplicationUser> GetUsers() 
{ 
    var users = _context.AppUsers.ToList(); 
    return users; 
} 

にアクセスすることができ、スタートアップ

で完全に罰金設定私はリポジトリを使用すべきであることを知っており、一度これを正しく理解することができます。インフラストラクチャプロジェクトでクラスを設定するにはどうすればよいのですか?起動時にDbContextを作成し、パラメータとして渡す必要はありません。

補遺:Nkosiが提供する答えを使用して

、私は、コントローラ内のデータサービスを挿入し、それを使用することができます。

しかし、私は私のリポジトリとUOWを実装して別々のインフラプロジェクト(Asp.netコア2クラスライブラリ)、

public class GenericRepository<T> : IRepository<T> where T : class 
{ 
    public GenericRepository() 
    { 

    } 
    //rest of code removed 
} 

がどのように私はDbContextが注入され得ることができますがありますか? DbContextをラップするためのIDbContextインターフェイスを作成し、起動時に登録する必要がありますか?

+0

に依存するようにコントローラをリファクタリング。フレームワークはサービスの解決を処理します – Nkosi

+0

あなたの 'DatabaseService'はリポジトリとまったく同じように見えます....あなたはすでにそれを理解しました –

答えて

1

あなたがあなたのサービス

public interface IDatabaseService { 
    List<ApplicationUser> GetUsers(); 
    //... 
} 

public class DatabaseService : IDatabaseService { 

    public DatabaseService(ApplicationDbContext context) { 
     //...code removed for brevity 
    } 

    //...code removed for brevity 
} 

ために、次のしていると仮定すると、サービスは、明示的に実装がサービスコンテナから解決されているときに注入されますApplicationDbContextに依存します。

Startup.ConfigureServices

var connString = Configuration.GetSection("ApplicationConfiguration:ConnectionStrings:DefaultConnection").Value; 
services.AddDbContext<ApplicationDbContext>(options => 
     options.UseSqlServer(connString)); 
services.AddScoped<IDatabaseService, DatabaseService>(); 

でサービスを登録し、明示的にちょうど `DatabaseService`を登録して、コントローラにそれを注入サービス

private IDatabaseService ds; 
private IConfiguration Configuration { get; set; } 

public HomeController(IConfiguration configuration, IDatabaseService ds) { 
    this.ds = ds; 
    Configuration = configuration; 
} 

public IActionResult Index() { 
    var diUsers = ds.GetUsers(); 

    var svm = SettingsViewModel(); 

    return View(svm); 
} 
+0

@ Nkosi ...私はそのようにする方法を見ましたが、実際にDbContext。それをクリアしていただきありがとうございます。では、DatabaseServiceも使用する別のクラスライブラリプロジェクトを作成すればどうでしょうか?そこにDbContextを挿入するにはどうすればいいですか?あなたの答えでは、注入機能は常にWebアプリケーションに結合されているようです – dinotom

+0

@dinotomこの場合、コードは主にView(Webプロジェクト)に関連する実装の懸念事項である 'ApplicationDbContext'に結合されますが、他のプロジェクトでは抽象化を使用しても問題はありません。依存するクラスは、実行時に実現/解決される抽象に依存します。 – Nkosi

+0

@dinotomコードをDbContextにあまり依存しないようにすることをお勧めします。 DbContextは実装上の問題です。 – Nkosi

関連する問題