DEV Community

Naimul Karim
Naimul Karim

Posted on

Registering Multiple Implementations of the same Interface using Autofac vs using Built-In Asp .Net Core DI

Using Autofac Keyed Services

Using strings as Key multiple dependencies can be registered.

For example creating a Enum where each enum value corresponds to an implementation of the service:

Public Enum PaymentState { Online, Cash}
Enter fullscreen mode Exit fullscreen mode

The implementations are as below.

public class CardPaymentState : IPaymentState {}
public class CashPaymentState : IPaymentState {}
Enter fullscreen mode Exit fullscreen mode

The enum values can then be registered as keys for the implementations below.

var builder = new ContainerBuilder()

builder.RegisterType<CardPaymentState>().Keyed<IPaymentState>PaymentState.Online);

builder.RegisterType<CashPaymentState>().Keyed<IPaymentState>(PaymentState.Cash);
Enter fullscreen mode Exit fullscreen mode

Now they can be resolved like below.

var cardPayment = container.ResolveKeyed<IPaymentState>(PaymentState.Online)

var cashPayment = container.ResolveKeyed<IPaymentState>(PaymentState.Cash);
Enter fullscreen mode Exit fullscreen mode

*Using .Net Core Built-In DI *

Firstly a shared delegate has to be declared.

Public delegate IPaymentService PaymentServiceResolver(string key);
Then in startup.cs, the multiple concrete registrations and a manual mapping of those types have to be set.

services.AddTransient<CreditCardService>()
services.AddTransient<CashService>();
Enter fullscreen mode Exit fullscreen mode
services.AddTransient<PaymentServiceResolver>(serviceProvider => key =
{
    switch (key)
    {
        case "online":
            return serviceProvider.GetService<CreditCardService>();

        case "cash":
            return serviceProvider.GetService<CashService>();

        default:
            throw new KeyNotFoundException();
    }
});
Enter fullscreen mode Exit fullscreen mode

Now it can be used from any class registered with DI.

public class Payment
{
    private readonly IPaymentService  paymentService;
    public Consumer(PaymentServiceResolver paymentServiceResover)
    {
       paymentService= paymentServiceResover("Online");
    }
    public void PayByCard()
    {
       paymentService.ProcessPayment();
    }
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)