繁体   English   中英

简单注入器的策略模式

[英]Strategy Pattern with Simple Injector

我有一个工作流,需要根据运行时数据使用特定的服务类。

例如。 我有一个具有IEmailService依赖项的SendEmailCommandMandrillEmailServiceSmtpEmailService 2种实现。

SendEmailCommand将确定它在运行时使用的IEmailService实现。

每个电子邮件服务实现都有自己的依赖关系,这些依赖关系由Simple Injector连接。

我不确定SendEmailCommand将如何确定要使用的实现( IEmailService )或如何将这些服务与运行时数据连接起来。

一些代码:

SendEmailCommand.cs处理程序

public void Handle(SendEmail command) {
  IEmailService service;

  if(/* some condition */) {
    service = // What to do here?
  } else {
    service = // What to do here?
  }
}

服务可以用我猜到的策略代替。

对我而言,最明显的解决方案是定义一个新的抽象,该抽象允许在向其提供运行时数据的同时分派到邮件服务实现。 可能看起来像这样:

interface IMailServiceDispatcher
{
    void Send([runtime data], [mail service arguments]);
}

这使您的命令处理程序成为:

private readonly IEmailServiceDispatcher dispatcher;
public void Handle(SendEmail command) {
  var data = /* runtime data */
  this.dispatcher.Send(data, /* mail service parameters */);
}

现在,您可以为IMailServiceDispatcher创建一个实现,如下所示:

class EmailServiceDispatcher : IEmailServiceDispatcher
{
    IMailService man; IMailService smtp;
    public EmailServiceDispatcher(IMailService man, IMailService smtp) { ... }

    public void Send(runtimeData, parameters) =>
        GetService(runtimedData).Send(parameters);

    private IMailService GetService(runtimeData) =>
        /* some condition using runtime data */ ? man : smtp;
}

您可以按以下步骤进行连接:

container.Register<IMailServiceDispatcher, MailServiceDispatcher>();
container.RegisterConditional<IMailService, MandrillEmailService>(WithParamName("man"));
container.RegisterConditional<IMailService, SmtpEmailService>(WithParamName("smtp"));

// Helper method
private static Predicate<PredicateContext> WithParamName(string name) =>
    c => c.Consumer.Target.Name == name;

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM