Как вводить услуги без их регистрации? Я имею в виду, что в прошлом некоторые каркасы DI автоматически регистрировали Service
for IService
.
Я в ситуации, когда у меня есть дюжина услуг, и в основном регистрация каждого из них - боль в заднице. так это поддерживается в каркасе DI DI asp.net?
Встроенный DI не поддерживает его и не намеревается сделать это. Встроенный контейнер IoC поддерживается просто по дизайну, чтобы обеспечить базовую инъекцию зависимостей, которая работает в большинстве случаев.
Если вам нужны расширенные функции, такие как регистрация по соглашению, сканирование сборок или поддержка декоратора, вам необходимо использовать сторонний контейнер IoC, такой как Autofac, SimpleInjector, Castle Windsor.
Я думаю, вам нравится, как он работает с 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"));
Не стесняйтесь настраивать эти расширения в соответствии с вашими потребностями. Например, вы можете запустить исключение, если не найдете реализации для некоторых служб, если это заставит вас чувствовать себя немного безопаснее.