В asp.net-mvc есть ли более элегантный способ использования IOC для внедрения нескольких репозиториев в контроллер? - PullRequest
1 голос
/ 05 сентября 2011

У меня есть веб-сайт asp.net-mvc, и я использую ninject для IOC и nhibernate для своего сопоставления ORM

Вот мой код привязки IOC:

internal class ServiceModule : NinjectModule
{
    public override void Load()
    {
        Bind(typeof(IIntKeyedRepository<>)).To(typeof(Repository<>)).InRequestScope();
    }
}

и вотпример того, как я делаю IOC в коде моего контроллера:

    public FAQController(IIntKeyedRepository<FAQ> faqRepository, IUnitOfWork unitOfWork)
    {
        _faqRepository = faqRepository;
        _unitOfWork = unitOfWork;
    }

Проблема в том, что до сих пор каждый контроллер имел одну таблицу, на которую он указывал, поэтому мне нужно было только передать класс репозитория вэто ...

Теперь у меня есть несколько таблиц и классов, у которых всего 2 поля:

  • Id
  • Имя

для каждого из этих классов я просто наследую от базового класса с именем:

 BaseModel

, который просто:

public class BaseModel
{
    public virtual string Name { get; set; }
    public virtual int Id { get; set; }
}

Я хочу иметь один:

 StaticDataController

класс, который может делать все CRUD для каждого класса, который просто наследуется от BaseModel (без дополнительных полей)

Глупо простым способом было бы сделать это:

    private readonly IIntKeyedRepository<Object1> _object1Repository;
    private readonly IIntKeyedRepository<Object2> _object2Repository;
    private readonly IIntKeyedRepository<Object3> _object3Repository;
    private readonly IIntKeyedRepository<Object4> _object4Repository;
    private readonly IIntKeyedRepository<Object5> _object5Repository;

    public StaticDataController(IIntKeyedRepository<Object1> obj1Repository, IIntKeyedRepository<Object2> obj2Repository, IIntKeyedRepository<Object3> obj3Repository, IIntKeyedRepository<Object4> obj4Repository, IIntKeyedRepository<Object5> obj5Repository)
    {
        _obj1Repository= obj1Repository;
        _obj2Repository= obj2Repository;
        _obj3Repository= obj3Repository;
        _obj4Repository= obj4Repository;
        _obj5Repository= obj5Repository;
    }

Так как я передаю таблицу в качестве параметра моим методам, мне нужно иметь какое-то выражение switch в моей контроллер, чтобы получить правильный класс репозитория на основе строки параметра.

Я предполагаю, что должен быть намного более элегантный способ поддержать то, что я пытаюсь сделать, поэтому я хотел посмотреть, есть ли лучшая практиказдесь (наследование контроллера, рефлексия и т. д.)?

Ответы [ 3 ]

9 голосов
/ 05 сентября 2011

Если вам нужно сделать это, это означает, что ваш контроллер делает слишком много вещей и убедительно указывает на то, что ему требуется уровень обслуживания.В этом случае я депортирую эти репозитории на сервисный уровень.Поэтому мой контроллер использует службу вместо нескольких репозиториев:

private readonly IStatisticDataService _service;

public StaticDataController(IStatisticDataService service)
{
    _service = service;
}

Сервис имеет бизнес, который может состоять из нескольких CRUD-методов атомарного репозитория.

Я знаю, что вы можете сказать: да,но теперь я должен внедрить все эти репозитории в реализацию интерфейса IStatisticDataService.Да, но было бы более разумно объединять эти атомарные операции CRUD на уровне обслуживания, а не в контроллере.

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

Теперь у меня есть несколько таблиц и классов, у которых всего 2 поля:

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

1 голос
/ 09 сентября 2011

Как отметил Марк Симанн: «Это нормально, но как только вы почувствуете, что контроллер слишком перегружен, вы можете реорганизовать его зависимости в агрегированную службу».

Посмотрите на: BestPractices: Допустимо ли использовать более одного хранилища в MVC-контроллере?

1 голос
/ 05 сентября 2011

Дарин абсолютно прав.Хотелось бы добавить, что если вы используете MVC 3, вам следует использовать пакет nuget Ninject.MVC3, а не создавать собственный служебный модуль.

...