クラス内に、リポジトリ パターンとして機能する次のジェネリック メソッドがあります。
public DbSet<T> GetAll<T>() where T : class
{
return dbContext.Set<T>();
}
ここで、特定のインターフェイス ( ) を実装するエンティティ クラスに属する、データベース内のすべてのエンティティのリストを取得したいと考えていますIChangeTrackingEntity
。したがって、現在、これに準拠する約 10 の特定のテーブル/クラスがありますが、これらのテーブルに 10 個のハードコードされた呼び出しを追加したくないので、代わりにリフレクションを使用して実行したいと思います (実装するクラスがこのインターフェイスは将来変更されるので、ここでも変更してコードを相互に依存させることを覚えておく必要はありません)。
動作するが、私が望まないコードの例:
var result = new List<IChangeTrackingEntity>();
using ( var repository = new DbRepository())
{
result.AddRange( repository.GetAll<FirstTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<SecondTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<ThirdTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<FourthTypeThatImplementsInterface>() );
result.AddRange( repository.GetAll<FifthTypeThatImplementsInterface>() );
}
return result;
私はかなり近づいていますが、Invoke
バックの結果を正しい型にキャストする最後の部分を機能させることができません。私が現在得たものはこれです:
var result = new List<IChangeTrackingEntity>();
var method = typeof (DbRepository).GetMethod("GetAll");
using ( var repository = new DbRepository())
{
foreach (var p in typeof(AnchorDbContext).GetProperties())
{
if (p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
{
var pType = p.PropertyType.GetGenericArguments()[0];
if (pType.GetInterface("IChangeTrackingEntity") != null)
{
var genericMethod = method.MakeGenericMethod(new[] {pType});
result.AddRange(genericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>);
}
}
}
return result;
}
object
Invoke 呼び出しが aを返し、それを基本的に にキャストする必要があるという上記の問題DbSet<pType>
。
現在のコードでgenericMethod.Invoke(repository, null) as DbSet<IChangeTrackingEntity>
はnull
、必要に応じて戻り値をキャストできないことを示す戻り値が返されるため、私が考えるインターフェイスではなく、特定の戻り値の型が必要です。
これを達成する方法のアイデアはありますか?