使用reflection将属性为IDbSet 的属性复制到另一个具有相同名称的List 的类上的属性?
我们在unit testing中有一个场景,我们创建了一个实现IDbSet的FakeDbSet。 在FakeUnitOfwork中,我有IDbSets属性并使用FakeDbSet进行新编辑。
无需在我的Commit方法中写出每个不同的属性,我试图使用reflection来迭代FakeUnitOfWork中的属性。 然后,我想将属性值复制到具有相同类型的List 属性的不同类。 所以我的FakeUnitOfWork中可能有一个属性:
IDbSet Users {get {return _users ?? (_users = new FakeDbSet());}
在我的假数据存储中,我有这个属性:
List 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复制到数据存储。 由于它们具有相同的名称,我只需要弄清楚如何通过reflection进行铸造。
更新:我试过这样的事情,并认为我可能会在正确的轨道上,但代码永远不会被击中:
foreach (var property in typeof(TestUnitOfWork).GetProperties()) { var testContextType = typeof (TestDataContext).GetProperty(property.Name); if(property.GetValue(this,null) is IDbSet) { testContextType.SetValue(TestDataContext, ((IDbSet) property.GetValue(this,null)).ToList(),null); } }
您使用reflection来获取上下文和工作单元的类型和属性。 现在,您在一侧具有List<>
类型的属性,并且您希望为其分配类型为IDbSet<>
的属性的内容。 这样对吗?
理论
为此,您需要在IDbSet<>
上调用ToList
方法,但此方法不是IDbSet<>
接口的一部分。 它是System.Linq.Enumerable
静态类中定义的扩展方法。 扩展方法只是带有语法糖的静态方法,但它仍然可以称为常规静态方法。 因此,您必须使用reflection(get type)查找Enumerable
类,获取ToList
方法的通用方法信息,并将其定位到正确的generics参数(由当前IDbSet<>
)。 然后,您可以将set作为参数传递给此方法并调用它。
无论如何,更好的方法是避免尽可能多的反思。 例如,在TestUnitOfWork
上TestUnitOfWork
可以直接访问列表的特殊接口。