Просто зарегистрируйте эти службы, используя его супер-интерфейс IExpirable будет работать
services.AddScoped<IExpirable, A>();
services.AddScoped<IExpirable, B>();
Однако будьте осторожны с этим конструктором
public HomeController(
IEnumerable<IExpirable> expirables,
IExpirableA expirableA,
IExpirableB expirableB)
{
}
Если вы не хотите получать подобные исключения
InvalidOperationException: Unable to resolve service for type 'IExpirableA' while attempting to activate 'HomeController'.
Вероятно, вы можете улучшить таким образом
services.AddScoped<IExpirable, A>();
services.AddScoped<IExpirable, B>();
services.AddDerivedExpirables(ServiceLifetime.Scoped);
с помощью IServiceCollection extension
public static class ServiceCollectionExtension
{
public static IServiceCollection AddDerivedExpirables(this IServiceCollection services, ServiceLifetime lifetime)
{
var scanAssemblies = AppDomain.CurrentDomain.GetAssemblies().ToList();
var interfaceTypes = scanAssemblies.SelectMany(o => o.DefinedTypes
.Where(x => x.IsInterface)
.Where(x => x != typeof(IExpirable)) // exclude super interface
.Where(x => typeof(IExpirable).IsAssignableFrom(x))
);
foreach (var interfaceType in interfaceTypes)
{
var types = scanAssemblies.SelectMany(o => o.DefinedTypes
.Where(x => x.IsClass)
.Where(x => interfaceType.IsAssignableFrom(x))
);
foreach (var type in types)
{
services.TryAdd(new ServiceDescriptor(interfaceType, type, lifetime));
}
}
return services;
}
}
Это расширение автоматически регистрирует все остальные интерфейсы, например IExpirableA
или IExpirableB
, производные от супер-интерфейса IExpirable . Попробуйте переключиться на свои нужды.
В OptionsServiceCollectionExtensions.cs есть пример, чтобы показать, как работает AddOptions () . Mayble полезно.