Содержание
Контроллеры в 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. Наиболее часто используемыми способами (и рекомендуемыми) можно считать способы получения через конструктор и с использованием атрибута.
