Как зарегистрировать универсальный интерфейс по его типу в DI-контейнере - PullRequest
0 голосов
/ 25 декабря 2018

Я хочу зарегистрировать некоторые универсальные интерфейсы, которые могут быть преобразованы в соответствующий реализованный класс.Я использую встроенное в Dependency Injection ядро ​​asp.net ( ServiceProvider ).

Предположим, что мой интерфейс выглядит следующим образом:

public interface ICommandHandler<in TCommand> where TCommand :Command
{
    void Execute(TCommand command);
}

, и мой класс такой:

public class AddItem1CommandHandler : ICommandHandler<AddItem1Command>

public class AddItem2CommandHandler : ICommandHandler<AddItem2Command>

и мои команды, как это явно в ограничении интерфейса, похожиthis:

public class AddItem1Command: Command
public class AddItem2Command: Command

Итак, я могу зарегистрировать их один за другим:

services.AddTransient<ICommandHandler<AddItem1Command>, AddItem1CommandHandler>();
services.AddTransient<ICommandHandler<AddItem2Command>, AddItem2CommandHandler>();

Проблема в том, что я вынужден определить регистрацию для каждой реализации.Теперь мой вопрос заключается в том, есть ли способ зарегистрировать все из них в одну строку, например:

services.AddScoped<ICommandHandler<Command>, Command>();

Я не знаю, как это возможно или нет с помощью ServiceCollection.

1 Ответ

0 голосов
/ 26 декабря 2018

ICommandHandler<> является универсальным типом, и я получаю всю реализацию из Assembly.

public static void Register(Assembly assembly, IServiceCollection services)
{        
    var allCommandHandler = assembly.GetTypes().Where(t =>
        t.IsClass &&
        !t.IsAbstract &&
        t.IsAssignableToGenericType(typeof(ICommandHandler<>)));
    foreach (var type in allCommandHandler)
    {
        var allInterfaces = type.GetInterfaces();
        var mainInterfaces = allInterfaces.Where(t => t.IsAssignableToGenericType(typeof(ICommandHandler<>)));
        foreach (var itype in mainInterfaces)
        {
            services.AddScoped(itype, type);
        }
    }
}

И я вызываю этот метод в dll, содержащем CommandHandler

...