Как получить словарь служб с ключами в ASP.NET Core 8

В ASP.NET Core 8 у нас есть возможность регистрировать службы с помощью ключа. Как правило, инъекцииIEnumerable<ICustom>в конструкторе вернет все службы, зарегистрированные вICustom.

Но как мне разрешить словарь службы вместе с ее ключами? Например,IDictionary<string, ICustom>чтобы я мог получить доступ как к сервису, так и к его ключу?

1 ответ

Я не нашел возможности сделать это из коробки, но вы можете попробовать сделать что-то самостоятельно, манипулируя дескрипторами сервисов. Что-то для начала:

      var services = new ServiceCollection();
services.AddKeyedSingleton("A", new MyTest("A"));
services.AddKeyedSingleton("B", new MyTest("B"));

var descriptors = services
    .Where(sd => sd.IsKeyedService && sd.ServiceType == typeof(MyTest));

services.AddSingleton<IDictionary<object, MyTest>>(p => descriptors
    .Select(d => d.ServiceKey)
    .Distinct()
    .ToDictionary(k => k, k => p.GetKeyedService<MyTest>(k)));

var sp = services.BuildServiceProvider();
var myTestClasses = sp.GetService<IDictionary<object, MyTest>>();

record MyTest(string Name);

Этот код можно сделать более универсальным, чтобы типы ключей и служб предоставлялись как параметры универсального типа:

      RegisterKeyedDictionary<string, MyTest>(services);

void RegisterKeyedDictionary<TKey, T>(ServiceCollection serviceCollection)
{
    var keys = serviceCollection
        .Where(sd => sd.IsKeyedService && sd.ServiceType == typeof(T))
        .Select(d => d.ServiceKey)
        .Distinct()
        .Select(k => (TKey)k)
        .ToList();

    serviceCollection.AddTransient<IDictionary<TKey, T>>(p => keys
        .ToDictionary(k => k, k => p.GetKeyedService<T>(k)));
}

var sp = services.BuildServiceProvider();
var myTestClasses = sp.GetService<IDictionary<string, MyTest>>();
Другие вопросы по тегам