Передача зависимостей в контроллер

Последнее обновление: 21.03.2022

Как и любой класс, контроллер может получать сервисы приложения через механизм 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;
}

В данном случае процесс установки зависимостей будет выглядеть следующим образом:

  1. Приложение получает запрос к методу контроллера HomeController

  2. Фреймворк MVC обращается к провайдеру сервисов для создания объекта контроллера HomeController

  3. Провайдер сервисов смотрит на конструктор класса HomeController и видит, что там имеется зависимость от интерфейса ITimeService

  4. Провайдер сервисов среди зарегистрированных зависимостей ищет класс, который представляет реализацию интерфейса ITimeService

  5. Если нужная зависимость найдена, то провайдер сервисов создает объект класса, который реализует интерфейс ITimeService

  6. Затем провайдер сервисов создает объект HomeController, передавая в его конструктор ранее созданную реализацию ITimeService

  7. В конце провайдер сервисов возвращает созданный объект HomeController инфраструктуре MVC, которая использует контроллер для обработки запроса

Передача зависимостей в методы. FromServices

Иногда зависимость используется только в одном методе. И в этом случае нет необходимости передавать ее в контроллер, поскольку она напрямую может быть внедрена в сам метод, который ее использует. Для передачи зависимости в метод применяется атрибут [FromServices]:

public string Index([FromServices] ITimeService timeService)
{
	return timeService.Time;
}

Атрибут FromServices предоставляется инфраструктурой MVC - он определен в пространстве имен Microsoft.AspNetCore.Mvc.

HttpContext.RequestServices

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

public string Index()
{
	ITimeService? timeService = HttpContext.RequestServices.GetService<ITimeService>();
	return timeService?.Time ?? "Undefined";
}
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850