«Переименовать» унаследованные методы в интерфейсе в C # - PullRequest
1 голос
/ 11 июля 2009

Я пытаюсь понять Repository Pattern при разработке приложения ASP.NET MVC (с использованием .NET 3.5, ASP.NET MVC 1.0 и Entity Framework). Я достаточно далеко продвинулся до внедрения зависимости и все работало с одним контроллером и одним типом сущности, но теперь я дошел до реализации поддержки отношений между различными типами, и я застрял.

Во всех примерах, которые я видел, интерфейс хранилища называется чем-то вроде IContactsRepository и содержит методы (CRUD), которые касаются только элементов Contact. Я хочу реализовать группировку Contacts, поэтому у меня есть тип сущности с именем Group и интерфейс IGroupRepository для обработки (CRUD) операций над группами.

  • Куда относится метод, относящийся к нескольким типам сущностей (в данном случае, например, к методу AddToGroup, который добавляет Contact к Group)?

Я сделал попытку большей структуры наследования для репозиториев, где я создал следующие интерфейсы:

ITypedRepository<T>
{
    IEnumerable<T> GetAll();
    T Get(int id);
    bool Add(T newObj);
    bool Edit(T editedObj);
    bool Delete(int id);
}

IContactsRepository : ITypedRepository<Contact> { }

IGroupsRepository : ITypedRepository<Group> {
    bool AddToGroup(int contactId, int groupId);
}

IRepository : IContactsRepository, IGroupsRepository

Затем я попытался создать главный репозиторий, который наследует IRepository, следующим образом:

public class EntitiesRepository : IRepository
{
    IEnumerable<Contact> IRepository<Contact>.Get()
    {
        throw new NotImplementedException();
    }
    IEnumerable<Group> IRepository<Group>.Get()
    {
        throw new NotImplementedException();
    }
    // Etc. All methods were generated by hitting [Ctrl]+[.] with the cursor on
    // the interface inheritance reference to IRepository and selecting
    // "Explicitly implement IRepository"
}

Как только я пытаюсь вызвать один из методов в репозитории из моего контроллера с этим кодом

var contacts = _repository.Get();

Я получаю сообщение об ошибке сборки о неоднозначности между Get<Contact>(), которая была унаследована через IContactsRepository и Get<Group>(), которая пришла через IGroupsRepository. Я понял, что это недопустимо, потому что IRepository наследует один и тот же универсальный интерфейс с разными типами (см. Пример 5 в связанной статье).

  • Теперь, поскольку я наследую через другие интерфейсы, есть ли шанс, что я смогу "переопределить имена" этих методов, например, как показано ниже?

    IContactsRepository : ITypedRepository<Contact>
    {
        IEnumerable<Contact> GetContacts = ITypedRepository<Contact>.Get();
        ...
    }
    

Таким образом, я могу получить к нему доступ с IRepository.Getcontacts без какой-либо двусмысленности. Возможно ли это, или есть какое-то решение этой проблемы?

И новый вопрос, для уточнения:

  • В любом случае можно указать в вызове от контроллера, какой из Get() методов мне нужен?

  • Каков наилучший способ решения моей первоначальной проблемы - необходимость в хранилище, которое обрабатывает много вещей, а не только один тип сущности?

РЕДАКТИРОВАТЬ: Добавлен пример кода Repository класса и вызов из Controller.

Ответы [ 3 ]

0 голосов
/ 11 июля 2009

Добавить методы с не однозначными именами, которые вызывают явные реализации:

public class EntitiesRepository : IRepository
{
    IEnumerable<Contact> IRepository<Contact>.Get()
    {
        // Return something
    }
    IEnumerable<Group> IRepository<Group>.Get()
    {
        // Return something
    }

    public IEnumerable<Contact> GetContacts()
    {
        return (this as IRepository<Contact>).Get();
    }

    public IEnumerable<Group> GetGroups()
    {
        return (this as IRepository<Group>).Get();
    }
}
0 голосов
/ 01 января 2010

Я думаю, вам не нужна вся эта сложность. Когда вы добавляете контакт в группу, вы меняете группу. Я предполагаю, что у вас есть коллекция контактов по групповому классу. После добавления контакта в группу просто необходимо сохранить группу. Так что вам действительно нужен метод AddContactToGroup, просто метод Save в интерфейсе репозитория Group сделает ту же работу. Также вам не нужен новый метод для каждого нового реляционного свойства в группе.

Для реализации самого метода Save, если вы используете NHibernate, единственное, что вам нужно сделать, это вызвать соответствующий метод.

0 голосов
/ 11 июля 2009

В вашем IGroupRepository, возможно, будут добавлены специализированные методы в дополнение к методам CRUD:

IGroupRepository : ITypedRepository<Group>
{
    bool AddContactToGroup(Group g, Contact C);
}
...