Скопировать свойство, которое является IDbSet <T>, в свойство другого класса, который является списком <T>с такими же именами, используя отражение? - PullRequest
3 голосов
/ 11 декабря 2011

У нас есть сценарий в наших модульных тестах, где мы создали FakeDbSet, который реализует IDbSet. В 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);
                   }


                }

1 Ответ

2 голосов
/ 12 декабря 2011

Вы использовали отражение, чтобы получить типы и свойства для своего контекста и единицы работы.Теперь у вас есть свойство типа List<> с одной стороны, и вы хотите присвоить ему содержимое свойства типа IDbSet<>.Правильно ли это?

Теория

Для этого вам нужно вызвать метод ToList для IDbSet<>, но этот метод не является частью интерфейса IDbSet<>.Это метод расширения, определенный в System.Linq.Enumerable статическом классе.Метод расширения - это просто статический метод с синтаксическим сахаром, но его все равно можно назвать обычным статическим методом.Таким образом, вы должны искать класс Enumerable, используя отражение (получить тип), получать общую информацию о методе для метода ToList и указывать на соответствующий общий аргумент (используемый текущим IDbSet<>).Затем вы можете передать свой набор в качестве параметра этому методу и вызвать его.

В любом случае, лучший подход - избегать как можно большего количества отражений.Например, предоставьте специальный интерфейс для TestUnitOfWork, который обеспечит прямой доступ к спискам.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...