Встроенное внедрение зависимостей с соглашениями

2

Как вводить услуги без их регистрации? Я имею в виду, что в прошлом некоторые каркасы DI автоматически регистрировали Service for IService.

Я в ситуации, когда у меня есть дюжина услуг, и в основном регистрация каждого из них - боль в заднице. так это поддерживается в каркасе DI DI asp.net?

  • 0
    Регистрация дюжины услуг - это боль? В самом деле?
  • 0
    Ну, я считаю, чтобы выдержать эту боль и зарегистрировать ее вручную. Многие другие разработчики убьют вас, когда наткнутся на магию вуду, которая регистрирует все, что они пишут.
Показать ещё 9 комментариев
Теги:
asp.net-core
dependency-injection

3 ответа

1
Лучший ответ

Встроенный DI не поддерживает его и не намеревается сделать это. Встроенный контейнер IoC поддерживается просто по дизайну, чтобы обеспечить базовую инъекцию зависимостей, которая работает в большинстве случаев.

Если вам нужны расширенные функции, такие как регистрация по соглашению, сканирование сборок или поддержка декоратора, вам необходимо использовать сторонний контейнер IoC, такой как Autofac, SimpleInjector, Castle Windsor.

  • 0
    Правильно. StructureMap поддерживает это одной строкой. Autofaq может легко сделать это с соглашением также.
3

Я думаю, вам нравится, как он работает с Autofac:

var assembly = typeof(MyModule).Assembly;
builder.RegisterAssemblyTypes(assembly)
    .Where(t => t.Name.EndsWith("Service"))
    .AsImplementedInterfaces()
    .InstancePerLifetimeScope();

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

public static IServiceCollection AddSingletonsByConvention(this IServiceCollection services, Assembly assembly, Func<Type, bool> interfacePredicate, Func<Type, bool> implementationPredicate)
{
    var interfaces = assembly.ExportedTypes
        .Where(x => x.IsInterface && interfacePredicate(x))
        .ToList();
    var implementations = assembly.ExportedTypes
        .Where(x => !x.IsInterface && !x.IsAbstract && implementationPredicate(x))
        .ToList();
    foreach (var @interface in interfaces)
    {
        var implementation = implementations.FirstOrDefault(x => @interface.IsAssignableFrom(x));
        if (implementation == null) continue;
        services.AddSingleton(@interface, implementation);
    }
    return services;
}

public static IServiceCollection AddSingletonsByConvention(this IServiceCollection services, Assembly assembly, Func<Type, bool> predicate)
    => services.AddSingletonsByConvention(assembly, predicate, predicate);

Теперь вы можете зарегистрировать все свои услуги простым кодом:

var assembly = typeof(MyType).Assembly;
services.AddSingletonsByConvention(assembly, x => x.Name.EndsWith("Service"));

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

1

Я хотел бы упомянуть Scrutor NuGet, которые позволяют использовать инъекции ASP.NET ядра Dependency, но добавляет беглый интерфейс поверх него, чтобы для конфигурации конвенции на основе.

Прочтите эту статью для получения дополнительной информации.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню