Last active
December 23, 2024 20:22
-
-
Save gusarov/ca587260923c606590994299d7bad60f to your computer and use it in GitHub Desktop.
Resolve keyed service by name with convenient generic interface with double arity match
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Microsoft.Extensions.DependencyInjection; | |
using Microsoft.Extensions.Hosting; | |
using System.Collections; | |
using System.Diagnostics.CodeAnalysis; | |
var appBuidler = Host.CreateApplicationBuilder(); | |
appBuidler.Services.AddKeyedSingleton<IService, Serivce1>("abc"); | |
appBuidler.Services.AddKeyedSingleton<IService, Serivce2>("def"); | |
appBuidler.Services.AddSingleton<Test>(); | |
appBuidler.Services.AddSingleton(typeof(IReadOnlyDictionary<,>), typeof(NamedKeyResolver<,>)); | |
var app = appBuidler.Build(); | |
Console.WriteLine(app.Services.GetRequiredKeyedService<IService>("abc")); | |
Console.WriteLine(app.Services.GetRequiredKeyedService<IService>("def")); | |
foreach (var item in app.Services.GetServices<IService>()) | |
{ | |
Console.WriteLine(item.GetType().Name); | |
} | |
app.Services.GetServices<Test>(); | |
interface IService | |
{ | |
} | |
class Serivce1 : IService | |
{ | |
} | |
class Serivce2 : IService | |
{ | |
} | |
class Test | |
{ | |
public Test(IReadOnlyDictionary<string, IService> services) | |
{ | |
Console.WriteLine(services["abc"].GetType().Name); | |
Console.WriteLine(services["def"].GetType().Name); | |
} | |
} | |
class NamedKeyResolver<TKey, TValue> : IReadOnlyDictionary<TKey, TValue> | |
{ | |
private readonly IServiceProvider _keyedServiceProvider; | |
public NamedKeyResolver(IServiceProvider keyedServiceProvider) | |
{ | |
_keyedServiceProvider = keyedServiceProvider; | |
} | |
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); | |
public TValue this[TKey key] | |
{ | |
get | |
{ | |
TryGetValue(key, out var value); | |
if (value == null) | |
{ | |
throw new KeyNotFoundException(key?.ToString()); | |
} | |
return value; | |
} | |
} | |
public IEnumerable<TKey> Keys => throw new NotImplementedException(); | |
public IEnumerable<TValue> Values => throw new NotImplementedException(); | |
public int Count => throw new NotImplementedException(); | |
public bool ContainsKey(TKey key) | |
{ | |
return TryGetValue(key, out _); | |
} | |
public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() | |
{ | |
throw new NotImplementedException(); | |
} | |
public bool TryGetValue(TKey key, [MaybeNullWhen(false)] out TValue value) | |
{ | |
value = _keyedServiceProvider.GetKeyedService<TValue>(key); | |
return value != null; | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment