【问题标题】:Dependency Injection - How to resolve a dependency based on the value and not type?依赖注入 - 如何根据值而不是类型来解决依赖关系?
【发布时间】:2017-10-25 15:47:18
【问题描述】:

我的应用程序中有一个接口和两个类(从该接口实现),如下所示:

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

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

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

在我的应用程序的某些地方,我需要使用 NexmoProvider,而在某些地方,我需要使用 TwilioProvider。这是根据以下枚举变量的值决定的:

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

我在我的应用程序中使用服务堆栈,并且有以下代码来解决依赖关系:

container.RegisterAutoWiredAs<TwilioProvider, ISMSServiceProvider>();

但正如您所见,ISMSServiceProvider 中没有任何内容可以让我同时注册两种不同的类型。

谁能建议我在下面的结构中可能需要做哪些更改以使我能够在运行时使用 Nexmo 或 Twilio 提供程序类?

【问题讨论】:

    标签: c# .net dependency-injection interface servicestack


    【解决方案1】:

    每个接口或类型只能有一个单个注册,因此此注册:

    container.RegisterAutoWiredAs<TwilioProvider, ISMSServiceProvider>();
    

    从接口解析时将返回TwilioProvider 的实例,例如:

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

    如果您希望能够同时注册这两种类型,您可以针对具体类型进行注册,例如:

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

    解决方法:

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

    如果你想使用 Enum 来解析,你可以注册一个工厂,例如:

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

    你可以在你的服务中注入:

    public SmsFactory SmsFactory { get; set; }
    

    然后正常使用,即:

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

    【讨论】:

    • 感谢您的回复,mythz... 我认为在这种情况下工厂解决方案看起来更明智。只是想知道我需要安装什么软件包才能获得“HostConfig”?我正在使用 ServiceStack 3.9.48
    • @Nirman 当您使用servicestack 哈希标签时,您指的是ServiceStack 的最新v4,您need to use the servicestack-bsd tag 指的是ServiceStack v3。你应该可以用AppHostBase.Instance.Resolve&lt;T&gt;之类的,不记得了。
    • 谢谢,它的“AppHostBase.Resolve”适用于 v3。感谢您帮助我正确实施。谢谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 2019-11-25
    • 1970-01-01
    • 2010-11-29
    • 2012-01-31
    相关资源
    最近更新 更多