Содержание
В предыдущей части мы вкратце познакомились с Dependency Injection в ASP.NET и даже смогли на простейшем примере посмотреть как регистрируются сервисы в контейнере DI и используются приложением. Сегодня разберемся подробнее с разработкой собственных сервисов в ASP.NET Core
Пример сервиса
Пусть, например, нам необходимо получать от пользователя в запросе какую-либо строку и формировать на её основе различные хэши (MD5, SHA256 и т.д.). Используя сведения из предыдущей части, мы можем написать следующий код сервиса ASP.NET Core:
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)));
}
}
У интерфейса IHashCalculator определен метод GetHash, который на основании строки data формирует хэш. Конкретные реализации этого интерфейса — два класса: MD5Hash и SHA256Hash. Теперь мы можем добавить IHashCalculator в список сервисов приложения и использовать этот сервис:
public class Program
{
public static void Main(string[] args)
{
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddTransient<IHashCalculator, MD5Hash>(); //регистрируем сервис
var app = builder.Build();
app.Run(async context =>
{
var svc = app.Services.GetService<IHashCalculator>();//получаем сервис
var request = context.Request;
var data = request.Query["data"].ToString();
if (string.IsNullOrEmpty(data))
await context.Response.WriteAsync("Empty data");
else
{
await context.Response.WriteAsync($"HASH: {svc?.GetHash(data)}");
}
});
app.Run();
}
Здесь мы зарегистрировали сервис в контейнере DI перед построением приложения и, затем получили его в middleware. При этом строка data отправляется пользователем через параметры запроса. Работающее приложение будет выглядеть следующим образом:
Так как ASP.NET Core сопоставила IHashCalculator с конкретной реализацией интерфейса — MD5Hash при регистрации сервиса, то в результате мы получаем MD5-хэш. Можем поменять реализацию интерфейса и получить хэш SHA-256:
builder.Services.AddTransient<IHashCalculator, SHA256Hash>(); //регистрируем сервис
Сервис без реализации интерфейса
ASP.NET Core позволяет регистрировать конкретные классы как сервисы. Например, мы можем создать такой класс:
public class Hash
{
public string GetMD5(string data)
{
return Convert.ToHexString(MD5.HashData(Encoding.ASCII.GetBytes(data)));
}
public string GetSHA256(string data)
{
return Convert.ToHexString(SHA256.HashData(Encoding.ASCII.GetBytes(data)));
}
}
затем, зарегистрировать его в контейнере DI следующим образом:
builder.Services.AddTransient<Hash>(); //регистрируем сервис
и использовать конкретный класс как сервис:
app.Run(async context =>
{
var svc = app.Services.GetService<Hash>();//получаем сервис
var request = context.Request;
var data = request.Query["data"].ToString();
if (string.IsNullOrEmpty(data))
await context.Response.WriteAsync("Empty data");
else
{
await context.Response.WriteAsync($"MD5: {svc?.GetMD5(data)} \r\n");
await context.Response.WriteAsync($"SHA-256: {svc?.GetSHA256(data)}");
}
});
Создание методов расширения для регистрации сервисов
Как мы уже знаем, для регистрации сервисов могут использоваться методы расширения IServiceCollection, которые имеют общую структуру имени Add[имя_сервиса]. Мы также можем создавать свои методы расширения для регистрации своих сервисов, например:
public static class ServiceProviderExtensions
{
public static void AddHash(this IServiceCollection services)
{
services.AddTransient<Hash>();
}
}
и затем использовать этот метод расширения для регистрации сервиса:
//builder.Services.AddTransient<Hash>(); builder.Services.AddHash();
Результат работы приложение будет точно таким же, как и в предыдущем примере.
Итого
Сегодня мы подробнее разобрались с тем, как создавать и регистрировать свои сервисы в ASP.NET Core. При этом, в качестве сервиса может выступать конкретный класс без реализации какого-либо интерфейса. Также научились создавать методы расширения для регистрации сервисов в контейнере DI.


