2

В моем приложении ASP.NET MVC все контроллеры используют этот объект ApplicationDbContext. В настоящий момент он создается внутри контроллера контроллера, но это жесткая связь и не является хорошей практикой.Как передать ApplicationDbContext в конструктор MVC5 ASP.NET?

public MessagesController() 
    { 
     this.Db = new ApplicationDbContext(); 
     this.Mapper = new MessageMapper(Db); 
     this.Service = new MessageService(); 
    } 

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

public MessagesController(ApplicationDbContext context){ 
    this.Db = context; 
    this.Mapper = new MessageMapper(Db); 
    this.Service = new MessageService(); 
} 

Вопрос заключается в том, как достичь этого? Я попытался найти исходный код, который контролирует инъекцию зависимостей контроллера, но он поставляется как файл .NET dll, и я не могу изменить (так же, как вы не можете редактировать файлы пространства имен System). Итак, как возможна инъекция зависимости для контроллеров в ASP.NET MVC? Может ли кто-нибудь использовать мой сценарий в качестве примера? Благодарю.

+2

Есть много рамок IoC с MVC адаптерами. См. Http://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection для Unity – haim770

+0

На самом деле вы также хотите передать Сервис как зависимость. Если Mapper на самом деле является репозиторием, тогда он должен быть введен вместо ApplicationDbContext, который является детальностью _sistence.Btw, правильно используя DI, вы вводите в конструктор только сервисы (репозиторий - это тоже сервис), а не все зависимости, необходимые для выполнения самих действий. – MikeSW

+0

Спасибо за ваш совет. Также мне было интересно, если я хочу добавить что-то вроде Controller.Server в класс под названием ImageUploadService, как я могу это сделать? Проблема в том, что Controller.Server недоступен внутри конструктора контроллера, но доступен только в действиях контроллера. Я хочу, чтобы Controller.Server передавался как зависимость, всегда является тем же самым экземпляром. –

ответ

1

Установите этот пакет:

Install-Package Unity.Mvc5 

В вашем Application_Start() добавьте следующую строку:

protected void Application_Start() 
    { 
    AreaRegistration.RegisterAllAreas(); 
    UnityConfig.RegisterComponents();       // <----- Add this line 
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
    RouteConfig.RegisterRoutes(RouteTable.Routes); 
    BundleConfig.RegisterBundles(BundleTable.Bundles); 
    } 

В UnityConfig зарегистрировать тип:

container.RegisterType<ApplicationDbContext>(); 

Done.

Обновление Кстати, сделав это, вы просто переместите код, который создает новый объект для Unity. Купите, вы все еще ждете конкретного класса. Кроме того, у вас будут все операции манипулирования данными в вашем контроллере (read: UI). Если вы действительно хотите избавиться от жесткой связи, вы можете взглянуть на образец DAO. http://en.wikipedia.org/wiki/Data_access_object

+1

Спасибо за ваш совет. Итак, Unity похож на контейнер для инъекций зависимостей? Что такое magic behend container.RegisterType ()? Создает ли объект ApplicationDbContext, когда класс запрашивает эту зависимость? –

+1

Также есть проблема. Контроллеры ASP.NET MVC5 поставляются с методом dispose, который предоставляет объект ApplicationDbContext при сборке мусора контроллера. Если контроллеры даже не знают ApplicationDbContext, как я могу реорганизовать этот Controller.Dispose() \ method? Могу ли я переместить логику в репозиторий и вызвать Repository.Dispose()? –

0

Я дам вам мой подход к этому.

С дистанционным управлением вы не хотите, чтобы DBContext отображался непосредственно на контроллере. Infact, чтобы действительно оставить разделение проблем, вы не хотите, чтобы контроллер даже знал о DbContext.

Если где сказано, что компания планирует начать использовать другую технологию хранения данных, например, RavenDB или MongoDB, каждый из Ф.О. контроллеров будет необходимо рефакторинга. DbContext не является обязательным или полезным.

Я не знаю, что такое класс MessageMapper, но он принимает DbContext, и это тоже сломается.

Вам необходимо рассмотреть вопрос об использовании шаблона репозитория .

Прочтите эту статью, это должно помочь.

http://www.asp.net/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

+0

Да, это именно то, к чему я сейчас иду. Я рефакторинг приложения и передам репозиторий и Mapper в конструктор контроллера, без ApplicationDbContext в будущем. Mapper принимает DbContext в конструкторе по исторической причине, что плохо, потому что Mapper должен только отображаться между Model и ViewModels, а не для доступа к данным из базы данных. Вот почему я рефакторинг с шаблоном репозитория. Спасибо за ваши советы. –