C# 简单喷油器的策略模式

C# 简单喷油器的策略模式,c#,dependency-injection,simple-injector,C#,Dependency Injection,Simple Injector,我有一个工作流,其中我需要基于一些运行时数据使用特定的服务类 例如,我有一个sendmailcommand,它依赖于IEmailService,有两个MandrillEmailService和SmtpEmailService的实现 sendmailCommand将确定它在运行时使用的是IEmailService的哪个实现 每个电子邮件服务实现都有自己的依赖项,这些依赖项由简单的注入器连接起来 我不确定sendmailcommand将如何决定使用什么实现(IEmailService),或者如何用运

我有一个工作流,其中我需要基于一些运行时数据使用特定的服务类

例如,我有一个
sendmailcommand
,它依赖于
IEmailService
,有两个
MandrillEmailService
SmtpEmailService
的实现

sendmailCommand
将确定它在运行时使用的是
IEmailService
的哪个实现

每个电子邮件服务实现都有自己的依赖项,这些依赖项由简单的注入器连接起来

我不确定
sendmailcommand
将如何决定使用什么实现(
IEmailService
),或者如何用运行时数据连接这些服务

一些代码:

SendEmailCommand.cs处理程序

我猜,服务可以用一种策略来替代。

最明显的解决方案(对我来说)是定义一种新的抽象,它允许在向邮件服务实现提供运行时数据的同时向邮件服务实现进行调度。这可能是这样的:

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;
您可以按如下方式将其连接起来:

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;
container.Register();
容器。注册条件(带参数名(“man”));
container.RegisterConditional(带参数名(“smtp”));
//辅助方法
具有ParamName(字符串名称)=>
c=>c.Consumer.Target.Name==Name;