DDiVita
DDiVita

Reputation: 4265

Copy a property that is an IDbSet<T> to a property on another class that is a List<T> with the same names using reflection?

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

Answers (1)

Ladislav Mrnka
Ladislav Mrnka

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

Related Questions