Reputation: 4265
We have a scenario in our unit tests where we have created a FakeDbSet that implements IDbSet. In a FakeUnitOfwork I have properties that are IDbSets and getting new-ed up using the FakeDbSet.
Without having to write out each different property in my Commit method I am trying to use reflection to iterate over the properties inside the FakeUnitOfWork. I then want to copy the property values to a differnt class that has propertes of List<> of the same type. So I may have a property in my FakeUnitOfWork:
IDbSet<User> Users {get {return _users ?? (_users = new FakeDbSet<User>());}
In my fake data store I have this property:
List<User> Users {get;set;}
This is hwat I have so far:
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.
}
}
So, I am not sure how to know I am looking at, say, a IDbSet (from FakeUnitOfWork) and a List (from my fake memory data store) so that I can copy the data from FakeUnitOfWork over to the data store. Since they have the same names I only need to figure out how to do the casting via reflection.
Update: I tried something like this and thought I might be on the irght track, but the code never gets hit:
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);
}
}
Upvotes: 3
Views: 378
Reputation: 364279
You used a reflection to get types and properties for your context and unit of work. Now you have property of type List<>
on one side and you want to assign content of property of type IDbSet<>
to it. Is it right?
The theory
To do that you need to call ToList
method on IDbSet<>
but this method is not part of IDbSet<>
interface. It is extension method defined in System.Linq.Enumerable
static class. Extension method is just static method with syntactic sugar but it can still be called as normal static method. So you must lookup Enumerable
class using reflection (get type), get generic method info for ToList
method and target it to proper generic argument (used by current IDbSet<>
). Then you can pass your set as parameter to this method and invoke it.
Anyway better approach would be avoiding as many reflection as possible. For example expose special interface on TestUnitOfWork
which would offer direct access to lists.
Upvotes: 2