Microsoft Dependency Injection Keyed Services
Plugin for Microsoft.Extensions.DependencyInjection enabling registration of multiple service implementations under the same interface.
You can think about it as equivalent of Autofac Keyed Services or Ninject Named bindings.
Install package
dotnet add package MSDI.KeyedServices
Register service with one extensions method call passing key and registration action
public void ConfigureServices(IServiceCollection services)
{
services.AddKeyedService<IGreeter, EnglishGreeter, Language>(
key: Language.En,
registration: serviceCollection =>
{
serviceCollection.AddTransient<EnglishGreeter>();
});
}
Or do it separately
services.AddKeyedService<IGreeter, PolishGreeter, Language>(key: Language.Pl, registration: null);
services.AddTransient<PolishGreeter>();
In both cases, remember to not wire implementation types with service they implement.
To resolve registered services you have two options
[ApiController]
public class GreetingsController : ControllerBase
{
private readonly IKeyedServiceProvider<IGreeter, Language> _greeterProvider;
public GreetingsController(IKeyedServiceProvider<IGreeter, Language> greeterProvider)
{
_greeterProvider = greeterProvider;
}
[HttpGet, Route("api/hello")]
public IActionResult SayHello(string lang)
{
if (Enum.TryParse<Language>(lang, ignoreCase: true, result: out var language))
{
IGreeter greeter = _greeterProvider.GetKeyedService(language);
string greetings = greeter.Greet();
return Ok(greetings);
}
return BadRequest("Unknown language");
}
}
To try it out for yourself, download this repository, run MSDI.KeyedServices.Example
project and call http://localhost:59792/api/hello?lang=pl
in your browser.
You can find presented examples in GreetingsController
. Put some breakpoints and play around.
Sometime service locator pattern is a way to go.
Here is how you can use it with this library.
[HttpGet, Route("api/hello/en")]
public IActionResult SayHelloEn()
{
var keyedServiceProvider =
_serviceProvider.GetService(typeof(IKeyedServiceProvider<IGreeter, Language>))
as IKeyedServiceProvider<IGreeter, Language>;
IGreeter greeter = keyedServiceProvider.GetKeyedService(Language.En);
string greetings = greeter.Greet();
return Ok(greetings);
}