4

Так что в моем веб-API-отслеживании ошибок, основанных на CQRS, я реорганизую свой код, прежде чем прогрессировать и внедрять модульные тесты (которые, должно быть, должны были быть первыми); У меня есть этот класс и конструктор:Инъекция зависимостей: ASP vNext. Как это работает?

public class BugCommandHandler : IBugCommandHandler 
{ 
    private BugContext db; 

    public BugCommandHandler(BugContext bugContext) 
    { 
     db = bugContext; 
    } 

    //Interface implementation 
} 

В мой контроллер, у меня есть это:

public class BugsController : Controller 
{ 
    private IBugCommandHandler commandHandler; 
    private BugContext db; 

    public BugsController(BugContext bugContext, IBugCommandHandler bugCommandHandler) 
    { 
     db = bugContext; 
     commandHandler = bugCommandHandler; 
    } 
} 

И, наконец, в моем классе запуска, я ввел зависимость с

services.AddSingleton<IBugCommandHandler, BugCommandHandler>(); 

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

Как в настоящее время работают BugCommandHandler реализации, как если бы она была вызвана с контекстом базы данных в его конструктор (за кулисами «магии»)? Каков его «процесс достижения этого?

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

+1

Поскольку 'BugContext' является конкретным объектом, а не интерфейсом, который передается в конструктор, инфраструктура DI просто вызывает для вас конструктор по умолчанию и передает его. – DavidG

+0

@DavidG Спасибо, что подтвердили, что для меня. Может быть, это было не на 100% ясным в моей фразировке, однако, что я хотел бы знать просто _how_ он делает это. Поэтому я знаю ограничения на это и почему я могу/не могу делать с ним определенные вещи. –

+0

Чтобы быть более точным, в месте, где вы зарегистрировали свою конкретную реализацию, структура IoC проверила, какие конструкторы были доступны на 'BugCommandHandler', и нашел один конструктор, взяв аргумент типа' BugContext'. Это конструктор, который он будет использовать, когда запрашивается экземпляр 'IBugCommandHandler'. – Alex

ответ

6
  1. Когда вы звоните AddSingleton, регистрация типа хранится в контейнере DI. Код here.
  2. Когда вы добавляете услуги MVC, вызывая AddMvc, они добавляются в тот же контейнер DI, что и тип (ы) на шаге 1. Магия происходит here. Вот как контейнер переносится в стек и делится между компонентами.
  3. Когда MVC активирует ваш контроллер, он создаст экземпляр, используя типы в контейнере; это бывает here. В конце концов, вызывается this code. Он попытается разрешить эту службу и все ее зависимости, используя регистрацию в контейнере.

В вашем конкретном случае вам также необходимо зарегистрировать BugContext.

Вы можете найти полезную статью, которую я написал некоторое время назад о DI в ASP.NET 5. Это немного устарел с точки зрения кода, но принципы остаются теми же: http://blogs.msdn.com/b/webdev/archive/2014/06/17/dependency-injection-in-asp-net-vnext.aspx

Кроме того, если вы на самом деле хочу посмотреть, что происходит, взгляните на другую статью, которую я написал об отладке кода фреймворка в ASP.NET 5. Вы можете входить в MVC и видеть точный путь кода: http://blogs.msdn.com/b/webdev/archive/2015/02/06/debugging-asp-net-5-framework-code-using-visual-studio-2015.aspx. Если вы хотите увидеть весь код в своем сценарии, вам понадобятся источники для DependencyInjection и MVC.

+0

Абсолютно фантастический, спасибо. –

Смежные вопросы