Dependency injection. How to resolve dependency based on value and not type?

I have one interface and two classes (implemented from this interface) in my application as shown below:

public interface ISMSServiceProvider
{
    NotificationSentResponse Send(SMSMessage sms);
}

public class NexmoProvider: ISMSServiceProvider
{
    NotificationSentResponse Send(SMSMessage sms);
}

public class TwilioProvider: ISMSServiceProvider
{
    NotificationSentResponse Send(SMSMessage sms);
}

      

In some places in my application I need to use NexmoProvider and in some places TwilioProvider. This was assumed based on the value of the following enumeration variable:

public enum NotificationProvider
{   
    Twilio = 1,
    Nexmo = 2
}

      

I am using a service stack in my application and having the following code to resolve the dependency:

container.RegisterAutoWiredAs<TwilioProvider, ISMSServiceProvider>();

      

But as you can see, there is nothing in the ISMSServiceProvider that would allow me to register two different types at the same time.

Can anyone think of what changes I might need to the structure below to allow me to use any of the Nexmo or Twilio provider classes at runtime?

+3


source to share


1 answer


You can only have a single registration per interface or type so that this registration:

container.RegisterAutoWiredAs<TwilioProvider, ISMSServiceProvider>();

      

An instance will return TwilioProvider

when resolved from the interface, for example:

var smsProvider = container.Resolve<ISMSServiceProvider>();

      

If you want to be able to register both types, you can register on a specific type, for example:

container.RegisterAutoWired<TwilioProvider>();
container.RegisterAutoWired<NexmoProvider>();

      

Allowed:



var twilio = container.Resolve<TwilioProvider>();
var nexmo = container.Resolve<NexmoProvider>();

      

If you want to allow the use of Enum you can register a factory like:

public class SmsFactory
{
    public ISMSServiceProvider Resolve(NotificationProvider provider) =>
        provider == NotificationProvider.Twilio 
            ? HostConfig.Resolve<TwilioProvider>()
            : HostConfig.Resolve<NexmoProvider>();
}

container.Register(c => new SmsFactory());

      

What can you enter into your Service with:

public SmsFactory SmsFactory { get; set; }

      

Then use as usual, ie:

var smsProvider = SmsFactory.Resolve(NotificationProvider.Twilio);

      

+4


source







All Articles