2016-07-04 2 views
0

Я создал Generic выпадающий список для использования в мой контроллер:Repository в качестве параметра

GenericDropDownList("myDropDown"); 

    private void GenericDropDownList(string dropdownName, object selectedDepartment = null) { 

    var dropdownQuery = unitOfWork.SalesRepository.Get(orderBy: q => q.OrderBy(d => d.FirstName)); 

    ViewData[dropdownName] = new SelectList(dropdownQuery, "LastName", "LastName", selectedDepartment); 
    } 

Это, кажется, работает хорошо. То, что я пытаюсь это сделать unitOfWork.TestRepository динамичным, так что я могу использовать все доступные хранилища в функции:

GenericDropDownList("myDropDown", SalesRepository); 

    private void GenericDropDownList(string dropdownName, object repository, object selectedDepartment = null) { 

    var dropdownQuery = repository.Get(orderBy: q => q.OrderBy(d => d.FirstName)); 

    ViewData[dropdownName] = new SelectList(dropdownQuery, "LastName", "LastName", selectedDepartment); 
    } 

выше не работает. Я получаю следующую ошибку:

Error CS1061 'object' does not contain a definition for 'Get' and no extension method 'Get' accepting a first argument of type 'object' could be found

Возможно ли сделать выпадающее меню динамичным, как я хочу?

ответ

0

Класс object не имеет .Get поэтому имеет смысл, что это не скомпилируется.

dynamic Использование исправим это, потому что тогда .Get разрешен во время выполнения, хотя по цене исполнения, а также с риском возникновения ошибки во время выполнения, если .Get не существует во время выполнения.

Лучше на мой взгляд, использовать интерфейс:

private void GenericDropDownList(string dropdownName, IRepository repository, object selectedDepartment = null) 
{ 
    // ... 
} 

При использовании Entity Framework вы можете наложить этот интерфейс на Repository классов с помощью частичных классов:

public partial class ThisRepository : IRepository 
{ 
} 

public partial class ThatRepository : IRepository 
{ 
} 

Улов будет заключаться в том, что интерфейс может не определить свойство, такое как FirstName, поэтому вам либо нужно определить метод для этого, либо использовать Func<IRepository, string> для сортировочного бита.

0

Если вы хотите, чтобы динамический объект использовал тип dynamic.

Или попробуйте приведение его к соответствующему типу:

(repository as type).Get(...) 
0

Правильный подход будет иметь все ваши репозитории реализовать общий интерфейс с обычными методами.

Например, вы можете создать интерфейс IRepository или IRepository<TSource>, если хотите, чтобы он был более конкретным.

Проблема в том, что TSource должен иметь свойство FirstName в соответствии с ожидаемым кодом.

Вы уверены, что все репозитории будут иметь объекты с FirstName?

Если ответ нет, то вы не можете создать такой универсальный метод (Вы должны были бы пересмотреть свою логику, или создать специальный интерфейс, который будет иметь объекты с этим свойством, но вы не сможете передать в любой репозиторий, только те, которые реализуют этот интерфейс).

Если ответ да , то вы можете создать базовый класс для всех ваших исходных сущностей (BaseEntity, например), которые будут иметь FirstName собственности.

Предположив ответ был да, то вы можете изменить подпись вашего метода, чтобы:

private void GenericDropDownList(string dropdownName, IRepository<TSource> repository, object selectedDepartment = null) where TSource : BaseEntity 

Вы бы тогда быть в состоянии назвать его:

GenericDropDownList("myDropDown", SalesRepository); //SalesRepository should implement IRepository<Sale>, where Sale : BaseEntity