Как и любой класс, контроллер может получать сервисы приложения через механизм dependency injection. В контроллере это можно делать следующими способами:
Через конструктор
Через параметр метода, к которому применяется атрибут FromServices
Через свойство HttpContext.RequestServices
Например, пусть у нас есть следующий файл Program.cs:
var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllers(); // добавляем поддержку контроллеров builder.Services.AddTransient<ITimeService, SimpleTimeService>(); // добавляем сервис ITimeService var app = builder.Build(); // устанавливаем сопоставление маршрутов с контроллерами app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); public interface ITimeService { string Time { get; } } public class SimpleTimeService: ITimeService { public string Time => DateTime.Now.ToString("hh:mm:ss"); }
В данном случае определен интерфейс ITimeService и его реализация SimpleTimeService. И в приложении происходит регистрация сервиса ITimeService.
Когда приходит запрос к контроллеру, инфраструктура MVC вызывает провайдер сервисов для создания объекта HomeController. Провайдер сервисов проверят конструктор класса HomeController на наличие зависимостей. Затем создает объекты для всех используемых зависимостей и передает их в конструкторо HomeController для создания объекта контроллера, который затем обрабатывает запрос.
Например, получим зависимость в конструкторе контроллера:
public class HomeController : Controller { readonly ITimeService timeService; public HomeController(ITimeService timeServ) { timeService = timeServ; } public string Index() => timeService.Time; }
В данном случае процесс установки зависимостей будет выглядеть следующим образом:
Приложение получает запрос к методу контроллера HomeController
Фреймворк MVC обращается к провайдеру сервисов для создания объекта контроллера HomeController
Провайдер сервисов смотрит на конструктор класса HomeController и видит, что там имеется зависимость от интерфейса ITimeService
Провайдер сервисов среди зарегистрированных зависимостей ищет класс, который представляет реализацию интерфейса ITimeService
Если нужная зависимость найдена, то провайдер сервисов создает объект класса, который реализует интерфейс ITimeService
Затем провайдер сервисов создает объект HomeController, передавая в его конструктор ранее созданную реализацию ITimeService
В конце провайдер сервисов возвращает созданный объект HomeController инфраструктуре MVC, которая использует контроллер для обработки запроса
Иногда зависимость используется только в одном методе. И в этом случае нет необходимости передавать ее в контроллер, поскольку она напрямую может быть внедрена в сам метод, который ее использует. Для передачи зависимости в метод применяется атрибут [FromServices]:
public string Index([FromServices] ITimeService timeService) { return timeService.Time; }
Атрибут FromServices предоставляется инфраструктурой MVC - он определен в пространстве имен Microsoft.AspNetCore.Mvc.
В методах контроллера можно обращаться к объекту контекста запроса через свойство HttpContext, а через свойство HttpContext.RequestServices можно получить все зарегистрированные в приложении сервисы:
public string Index() { ITimeService? timeService = HttpContext.RequestServices.GetService<ITimeService>(); return timeService?.Time ?? "Undefined"; }