我们在单元测试中有一个场景,我们创建了一个实现IDbSet的FakeDbSet。在FakeUnitOfwork中,我有一些IDbSets属性,并使用FakeDbSet进行了新的编辑。
无需在我的Commit方法中写出每个不同的属性,我试图使用反射来迭代FakeUnitOfWork中的属性。然后,我想将属性值复制到具有List<>属性的不同类中。相同类型。所以我的FakeUnitOfWork可能有一个属性:
IDbSet<User> Users {get {return _users ?? (_users = new FakeDbSet<User>());}
在我的假数据存储中,我有这个属性:
List<User> Users {get;set;}
到目前为止,这是我所做的:
public void Commit()
{
foreach (var property in typeof(TestUnitOfWork).GetProperties())
{
var testContextType = typeof (TestDataContext).GetProperty(property.Name);
//I then want to do a ToList() on the TestUnitOfWork IDbSet properties to push them into the TestDataContext.
}
}
所以,我不知道如何知道我正在查看IDbSet(来自FakeUnitOfWork)和List(来自我的伪内存数据存储),以便我可以将数据从FakeUnitOfWork复制到数据存储。由于它们具有相同的名称,我只需要弄清楚如何通过反射进行转换。
更新:我尝试过这样的事情并认为我可能会处于不确定的轨道上,但代码永远不会受到影响:
foreach (var property in typeof(TestUnitOfWork).GetProperties())
{
var testContextType = typeof (TestDataContext).GetProperty(property.Name);
if(property.GetValue(this,null) is IDbSet<MyBaseEntityType>)
{
testContextType.SetValue(TestDataContext, ((IDbSet<MyBaseEntityType>) property.GetValue(this,null)).ToList(),null);
}
}
答案 0 :(得分:2)
您使用反射来获取上下文和工作单元的类型和属性。现在,您在一侧拥有类型为List<>
的属性,并且您希望为其分配类型为IDbSet<>
的属性的内容。是不是?
理论
为此,您需要在ToList
上调用IDbSet<>
方法,但此方法不属于IDbSet<>
界面。它是System.Linq.Enumerable
静态类中定义的扩展方法。扩展方法只是具有语法糖的静态方法,但它仍然可以称为常规静态方法。因此,您必须使用反射(获取类型)查找Enumerable
类,获取ToList
方法的通用方法信息,并将其定位到正确的通用参数(由当前IDbSet<>
使用)。然后,您可以将set作为参数传递给此方法并调用它。
无论如何,更好的方法是避免尽可能多的反思。例如,在TestUnitOfWork
上公开可以直接访问列表的特殊界面。