ASP.NETコアとEFコアで非汎用DbContextOptionsを安全に使用できますか?

asp.net-core asp.net-identity c# entity-framework-core

質問

ASP.NETコアでは、組み込みDIコンテナによってEFコアコンテキストが作成されます。 公式のドキュメントでは、一般的なDbContextOptions<TContext>してコンテキストが作成されます。

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コンテナではうまく動作しないからです。

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

受け入れられた回答

私は非ジェネリック型を使用したいと思います。なぜなら私のデザインでは抽象的なコンテキストがあり、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を取るDbContextOptions通常同様に動作します。通常、あなたは正しいでしょう、サービスプロバイダはこれを理解することができません。ただし、 serviceCollection.AddDbContext<ConcreteDbContext>(...)を呼び出すと、 DbContextOptionsインスタンスが要求されたときにDbContextOptions<ConcreteDbContext>インスタンスを提供する必要があることが、EFコアからサービスコンテナに通知されます。

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


人気のある回答

以下は、ベースのIdentityDbContextクラス(ジェネリックおよび非ジェネリック) コンストラクタのシグネチャです。

public IdentityDbContext(DbContextOptions options)

それは、問題なく、非汎用のDbContextOptions動作することを意味します。

実際、 DbContextOptionsクラスの汎用バージョンと非汎用バージョンの唯一の違いは、 汎用バージョンではabstract非汎用バージョンが実装されていることです。

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



Related

ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ