我在使用泛型按类型创建类的新实例时遇到问题。我想要做的是拥有一个可以使用 DBSet<> 或 FakeDBSet<> 创建的数据库上下文。FakeDBSet 将用于测试代码。我目前有一个完整的假数据上下文,但这是一种浪费,因为唯一真正的区别是使用的 DBSet。我已经研究过使用 Activator.CreateInstance() 没有太多运气。
例子:
public class Album {}
public class Artist {}
public class MusicStoreContext
{
public IDbSet<Album> Albums { get; set; }
public IDbSet<Artist> Artists { get; set; }
public MusicStoreContext(Type dbSetType)
{
Albums = new (dbSetType)<Album>;
Artists = new (dbSetType)<Artist>;
}
}
public class Startup
{
public Startup()
{
// Production code would do something like this:
MusicStoreContext context = new MusicStoreContext(typeof(DbSet<>));
// Test code would do something like this:
MusicStoreContext testContext = new MusicStoreContext(typeof(FakeDbSet<>));
}
}
我也尝试过这样的事情:
public class MusicStoreContext<T> where T : IDBSet
{
public IDbSet<Album> Albums { get; set; }
public IDbSet<Artist> Artists { get; set; }
...
由于乔恩的建议,这是我想出的有效方法:
public class MusicStoreContext
{
private IDbSet<Album> _Albums;
private IDbSet<Artist> _Artists;
public IDbSet<Album> Albums { get {return _Albums;} }
public IDbSet<Artist> Artists { get {return _Artists; }
public MusicStoreContext(Type dbSetType)
{
Albums = new (dbSetType)<Album>;
Artists = new (dbSetType)<Artist>;
}
public TaxDocumentsContext() : base()
{
CreateDbSets(new ProductionDbSetProvider());
}
public TaxDocumentsContext(IDbSetProvider provider)
{
CreateDbSets(provider);
}
private void CreateDbSets(IDbSetProvider provider)
{
provider.CreateDbSet<Album>(this, ref _Albums);
provider.CreateDbSet<Artist>(this, ref _Artists);
}
}
对于 DbSetProvider:
public interface IDbSetProvider
{
void CreateDbSet<T>(DbContext context, ref IDbSet<T> dbSet) where T : class;
}
public class FakeDbSetProvider : IDbSetProvider
{
public void CreateDbSet<T>(DbContext context, ref IDbSet<T> dbSet) where T : class
{
dbSet = new FakeDbSet<T>();
}
}
public class ProductionDbSetProvider : IDbSetProvider
{
public void CreateDbSet<T>(DbContext context, ref IDbSet<T> dbSet) where T : class
{
dbSet = context.Set<T>();
}
}
现在我可以轻松地测试,而无需使用 FakeDbSet 从此处访问数据库: http ://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with -a-通用存储库/