2017-01-06 2 views
1

ASP.NETコアでは、組み込みDIコンテナによってEFコアコンテキストが作成されます。 official documentationでは、コンテキストは、汎用DbContextOptions<TContext>で作成された:ASP.NETコアとEFコアで汎用でないDbContextOptionsを安全に使用できますか?

public class MyContext : IdentityDbContext<User> { 
    public MyContext(DbContextOptions<MyContext> options, ILogger<MyContext) logger) : base(options) { } 
} 

しかしながら、非ジェネリックの例が同様に存在する。

public class MyContext : IdentityDbContext<User> { 
    public MyContext(DbContextOptions options, ILogger<MyContext) logger) : base(options) { } 
} 

それらの間の差は、ソースコードに従います:

タイプパラメータ:TContext:これらのオプションが適用されるコンテキストのタイプ。

デザインでは抽象的なコンテキストがあり、DIコンテナでうまく動作しないため、非ジェネリックタイプを使用したいと思います。

したがって、非ジェネリックタイプを使用すると、実際にはどういう意味ですか?私のコンテキストは正しく構成されないでしょうか?

public IdentityDbContext(DbContextOptions options) 

私にはそれが問題なく非ジェネリックDbContextOptionsで作業できることを意味します。ここでは

答えて

3

私は非ジェネリック型を使用したいと思っています。私のデザインでは抽象的なコンテキストがあり、それはDIコンテナではうまく動作しません。

これはDIコンテナでうまくいきます。インスタンス化しようとしている型である最も派生した型だけを調べます。その間に基本クラスがあるという事実は関係ありません。

DbContextOptions<AbstractDbContext>は使用できませんが、必要はありません。あなたは、基本クラスがDbContextOptionsを取る作る、または汎用の基本クラスを作成し、DbContextOptions<ConcreteDbContext>取ることができますいずれか:私は非ジェネリック型を使用する場合は、だから、

abstract class AbstractDbContext : DbContext 
{ 
    protected AbstractDbContext(DbContextOptions options) : base(options) 
    { 
    } 
} 

class ConcreteDbContext : AbstractDbContext 
{ 
    public ConcreteDbContext(DbContextOptions<ConcreteDbContext> options) : base(options) 
    { 
    } 
} 

または

abstract class AbstractDbContext<TContext> : DbContext 
    where TContext : AbstractDbContext<TContext> 
{ 
    protected AbstractDbContext(DbContextOptions<TContext> options) : base(options) 
    { 
    } 
} 

class ConcreteDbContext : AbstractDbContext<ConcreteDbContext> 
{ 
    public ConcreteDbContext(DbContextOptions<ConcreteDbContext> options) : base(options) 
    { 
    } 
} 

をそれはどういう意味ですか?私のコンテキストは正しく構成されないでしょうか?

一般的ではないDbContextOptionsを取っているコンストラクタも通常動作します。通常、あなたは正しいでしょう、サービスプロバイダはこれを理解することができません。ただし、serviceCollection.AddDbContext<ConcreteDbContext>(...)に電話をかけたときに、DbContextOptionsインスタンスが要求されたときに、DbContextOptions<ConcreteDbContext>インスタンスを提供する必要があることが、EFコアからサービスコンテナに通知されます。

これは、コンテキストタイプが1つの場合にのみ機能することに注意してください。複数ある場合、サービスプロバイダーは必要な情報を把握するのに十分な情報がありません。

2

は基本IdentityDbContextクラス(ジェネリックと非ジェネリック)constructorの署名です。

実際にDbContextOptionsクラスのgenericnon genericバージョン間の唯一の違いは、ジェネリック版がabstract非ジェネリックバージョンを実装していることです。

DbContextOptions<YourDbContext>~YourDbContextコンストラクタを渡すことは、呼び出し元が抽象クラス(基本的にはContextTypeプロパティ)の正しい実装を確実に渡すため、より安全です。

+0

私はおそらく、ジェネリックでないものを使うのは安全だと思いますが、あなたのプロジェクトには2つの異なるコンテキストがあります。次に、各コンテキストが正しく構成されるように、汎用オプションclassを使用する必要があります。 – grokky

関連する問題