我在通過泛型類型創建類的新實例時遇到問題。我試圖做的是有一個數據庫上下文,可以使用DBSet <>或FakeDBSet <>創建。 FakeDBSet將用於測試代碼中。我目前有一個完整的虛擬datacontext,但它是一個浪費,因爲唯一真正的區別是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擊中DB測試: http://refactorthis.wordpress.com/2011/05/31/mock-faking-dbcontext-in-entity-framework-4-1-with-a-generic-repository/
喬恩,這沒有把戲。我不得不改變我的CreateDbSet()來處理DbSet沒有構造函數的事實。我已將更新的代碼添加到我的原始問題中。再次感謝。 –
@JonSkeet在你的例子中變量'dbSetType'的上下文中。什麼是'dbSetType'?我的假設是'DbSet <>',但是如果您嘗試在EF 5.0中使用Activator.CreateInstance()創建'DbSet',則會出現以下錯誤:'未找到類型的構造函數' –
@JohnHartsock: DbSet <>'的具體子類。 –