Dependency Injection в ASP.NET Core. Создание сервисов

В предыдущей части мы вкратце познакомились с 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.

Подписаться
Уведомить о
guest
0 Комментарий
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии