コメントで指摘されているように、リフレクションまたはプロジェクト内のタイプとして各エンティティを実装することはできません。
最後のアプローチは次のようになります。 IQueryable<T>
を実装する基本クラスを作成すると、新しいエンティティの追加に必要なコードが最小限に抑えられ、DbContext
が1つ以上注入可能な場合にも機能します。これはほとんどの場合、通常のデモアプリケーションで使用されます。
public abstract class QueryableEntityBase<TEntity> : IQueryable<TEntity> where TEntity : class
{
protected QueryableEntityBase(DbContext context)
{
Context = context ?? throw new ArgumentNullException(nameof(context));
Queryable = context.Set<TEntity>().AsQueryable();
}
public Type ElementType => Queryable.ElementType;
public Expression Expression => Queryable.Expression;
public IQueryProvider Provider => Queryable.Provider;
protected IQueryable<TEntity> Queryable { get; }
private DbContext Context { get; }
public IEnumerator<TEntity> GetEnumerator() => Queryable.GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => Queryable.GetEnumerator();
}
// You need to create this per entity you want to be injectable
public class MyQueryableEntity : QueryableEntityBase<MyEntity>
{
public MyQueryableEntity(ApplicationDbContext context) : base(context) { }
}
これは、あなたがIMongoClient
代わりのDbContext
を使用していますMonogoDbQueryableEntityBase<T>
とQueryableEntityBase<T>
ベースを変更することで、エンティティによって根本的なクエリ/永続性プロバイダを変更することができるという追加の利点を有します。
登録は、次の行に沿ったものでなければなりません(StructureMapに精通していない場合は、すべての型を登録したりアセンブリをスキャンする必要があります)。 1つのデータベースのみを持って、あなたはまた、基本クラスは非抽象作るだけQueryableEntity<T>
を解決できる単純な場合には
config.For(typeof(IQueryable<>)).Use(typeof(QueryableEntityBase<>));
、私はあなたがアプリごとに1つのDbContextの制限を打つだろうと述べたように遅かれ早かれ、明示的に行うのが最善です。
あなたも
public class QueryableEntityBase<TContext, TEntity> : IContextSetQueryable<TDbContext, TEntity>, IQueryable<TEntity> where TEntity : class, TContext : DbContext
{
private TContext Context { get; }
protected QueryableEntityBase(TContext context)
{
Context = context ?? throw new ArgumentNullException(nameof(context));
Queryable = context.Set<TEntity>().AsQueryable();
}
}
をコンテキストを定義することができます。しかし、あなたは追加のインタフェース必要なので、実装を拡張
または代わりに:次に
public interface IContextSetQueryable<TContext, TContext> : IQueryable<TEntity> where TContext : DbContext { }
あなたのサービスにIContextSetQueryable<TContext, TContext> entity
を注入します。
しかし、その後、あなたがDbContext
を参照する機能が必要になりますので、あなたは、持続性にとらわれないドメインを持っている能力を失うと、それはサブタイプですので、それは本当にエレガントではありませんし、あなたにも、このような
などのデータベース固有のインタフェースを、使用することができます
public interface ISomethingDatabase
{
IQueryable<User> Users { get; }
IQueryable<Customer> Customers { get; }
...
}
'Set'はコンパイル時にTを知っている必要があり、 'Set()のためのオーバーロードがないので、コンパイル時**の具体的な型を知っていても、タイプ(T)) 'なぜあなたのdbcontextの抽象クラスと単一の '.Set 'メソッドを書くのではないのですか?また、いくつかの欠陥としてあなたのデザイン。複数のコンテキストを持つ場合、各エンティティの実装を独自のクエリ可能なものとすることなく、どのエンティティから実装するかはわかりません。 –
Tseng
最も重要な部分は「IQueryableをなぜ注入しますか?間違ったデザインのように見える! –