Внедрение зависимости в два слоя в asp.net mvc - PullRequest
2 голосов
/ 02 марта 2012

Я пытаюсь получить все больше и больше знакомств с DI и IoC. На данный момент я понимаю концепцию и реализацию DI с контроллерами в приложении MVC. Но предположим, у меня есть многоуровневое приложение. Контроллеры вызывают businesslogic классы, а businesslogic класы вызывают классы репозитория.

Как настроить второй слой, часть businesslogic для репозитория с DI. Это гарантирует, что я могу тестировать на разных уровнях в моем приложении. Чего я не хочу делать, так это передавать зависимость в хранилище от контроллеров.

Надеюсь, что кто-то может дать намеки на это.

Patrick

Ответы [ 3 ]

7 голосов
/ 02 марта 2012

Минималистичный пример реализации с использованием Ninject . Это не абсолютная правда о DI / IoC, просто краткий пример того, как это можно сделать .

Конфигурация

// repositories
base.Bind<IMyRepository>().To<MyRepository>();

// services
base.Bind<IMyServices>().To<MyServices>();

Когда используется IMyRepository, он будет использовать конкретную реализацию MyRepository.

Контроллер

public class MyController : Controller
{
    private readonly IMyServices _myServices;

    public AnimalController(IMyServices myServices)
    {
        _myServices = myServices;
    }

    // your actions
} 

Опять же, внутри MyService есть аналогичный шаблон (инжектор конструктора)

Услуги

public class MyServices : IMyServices
{
    private readonly IMyRepository _myRepository;

    public MyServices(IMyRepository myRepository)
    {
        _myRepository = myRepository;
    }

    public void Example()
    {
        _myRepository.PleaseDoSomething();
    }
}

Также помните, что в ASP.NET MVC есть много других вещей, где может использоваться IoC:

  • локализация
  • разрешение
  • поставщик метаданных модели (например, локализованные сообщения об ошибках)
  • пользовательские модели переплетов
  • контроллер фабричный
  • и т.д.

Обновление

В примере кода произошла ошибка. Внедрение зависимостей не было сделано в сервисе. Теперь это должно быть правильно.

Обновление 2

Я думаю, что настоятельно рекомендуется использовать пакеты NuGet для начальной загрузки вашего приложения. Экономит время, может применить некоторые «лучшие практики», другие проекты получат аналогичную базу и т. Д. Вот несколько инструкций для разных IoC + MVC 3

2 голосов
/ 02 марта 2012

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

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

Затем вы ополаскиваете и повторяете конкретные классы бизнес-логики.

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

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

0 голосов
/ 02 марта 2012

Контейнер DI просто создает и разрешает зависимости для типов, для которых он настроен. Это не связано с тем, как вы проектируете свои прикладные уровни. Почему вы не хотите передать хранилище туда, где это нужно ?! Эти объекты зависят от абстракции, а не от реализации.

Контейнер DI настраивается для обслуживания определенного экземпляра репозитория в любом месте, где это требуется. Контроллер получает экземпляр репозитория, который затем может быть передан на бизнес-уровень для использования.

Разделение означает, что объект не зависит от деталей реализации, вот и все. Тестирование возможно, потому что зависимости выражены в виде интерфейсов, и вы можете имитировать их.

...