Содержание
Контроллеры в ASP.NET Core MVC могут использовать в работе различные сервисы. Для получения этих сервисов могут использоваться различные способы, которые мы сегодня рассмотрим.
Мы можем использовать следующие способы получения зависимостей в контроллере ASP.NET Core MVC:
- Через конструктор
- Через параметр метода, к которому применяется атрибут
FromServices
- Через свойство
HttpContext.RequestServices
рассмотрим эти способы на примере собственного сервиса.
Пример сервиса ASP.NET Core MVC
Для начала, создадим какой-нибудь сервис, с помощью которого будем рассматривать способы его получения в контроллере. Пусть наш сервис рассчитывает хэши для заданной строки:
using System.Security.Cryptography; using System.Text; namespace AspMvcFiles { public interface IHashCalculator { public string GetHash(string data); } public class MD5Hash : IHashCalculator { public string GetHash(string data) { return Convert.ToHexString(MD5.HashData(Encoding.ASCII.GetBytes(data))); } } public class SHA256Hash : IHashCalculator { public string GetHash(string data) { return Convert.ToHexString(SHA256.HashData(Encoding.ASCII.GetBytes(data))); } } }
Зарегистрируем этот сервис в контейнере DI. Для этого откроем файл Program.cs и добавим следующие строки в метод Main()
:
namespace AspMvcFiles { public class Program { public static void Main(string[] args) { var builder = WebApplication.CreateBuilder(args); builder.Services.AddControllersWithViews(); builder.Services.AddTransient<IHashCalculator, MD5Hash>();//регистрируем сервис var app = builder.Build(); if (!app.Environment.IsDevelopment()) { app.UseExceptionHandler("/Home/Error"); app.UseHsts(); } app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseRouting(); app.UseAuthorization(); app.MapControllerRoute( name: "default", pattern: "{controller=Home}/{action=Index}/{id?}"); app.Run(); } } }
Здесь мы зарегистрировали сервис и теперь можем использовать его реализацию в контроллерах ASP.NET Core MVC:
builder.Services.AddTransient<IHashCalculator, MD5Hash>();//регистрируем сервис
Получение сервиса через конструктор
Этот способ получения сервиса можно считать рекомендуемым. Именно такое получение сервиса мы видим, когда создаем свое первое приложение в ASP.NET Core MVC:
public HomeController(ILogger<HomeController> logger)
Перепишем конструктор контроллера HomeController
следующим образом:
private readonly IHashCalculator _hashCalculator; public HomeController(ILogger<HomeController> logger, IHashCalculator hashCalculator) { _logger = logger; _hashCalculator = hashCalculator; }
Получение сервиса через конструктор контроллера позволяет использовать этот сервис в любом месте класса контроллера. Например, напишем следующее действие:
public IActionResult GetHash(string data) { return Ok(new { Source = data, Result = _hashCalculator.GetHash(data) }); }
Результат работы действия:
Получение сервиса с использованием атрибута FromService
Иногда бывает так, что сервис необходимо использовать только в одном месте (или нескольких местах) контроллера и нет необходимости для этого заводить в классе контроллера отдельное поле. В этом случае, мы можем использовать атрибут FromService
для получения сервиса непосредственно через параметры метода контроллера:
public IActionResult GetHash(string data, [FromServices] IHashCalculator _hash) { return Ok(new { Source = data, Result = _hash.GetHash(data) }); }
Результат работы действия будет тот же, что и на рисунке выше.
Получение сервиса через свойство HttpContext.RequestServices
Этот способ можно обозначить как наименее рекомендуемый, так как в этом случае мы задействуем service locator, чего следует по возможности избегать при проектировании приложения. Но, если иного способа получения сервиса нет, то можем воспользоваться и таким подходом:
public IActionResult GetHash(string data) { var service = HttpContext.RequestServices.GetService<IHashCalculator>(); return Ok(new { Source = data, Result = service.GetHash(data) }); }
Итого
Для получения сервисов в контроллере ASP.NET Core MVC мы можем использовать различные способы — через конструктор, через свойство HttpContext.RequestServices
или с использованием атрибута FromService
. Наиболее часто используемыми способами (и рекомендуемыми) можно считать способы получения через конструктор и с использованием атрибута.