如何在电子邮件和短信类中使用DI

时间:2019-01-28 12:36:49

标签: c# asp.net-core dependency-injection .net-core

我有这个界面:

public interface IMessageSender
{
    Task SendMessageAsync(parameters);
}

和此类:

public class EmailSender : IMessageSender
{
}

public class SMSSender : IMessageSender
{
}

在我的控制器中,我像这样使用它们:

public class MyController : Controller
{
    private readonly IMessageSender _messageSender;
    public MyController(IMessageSender messageSender)
    {
        _messageSender = messageSender;
    }
}

我在此控制器中有两种方法:

public async Task<IActionResult> SendByEmail()
{ 
    await _messageSender.SendMessageAsync(parameters);
}

public async Task<IActionResult> SendBySMS()
{ 
    await _messageSender.SendMessageAsync(parameters);
}

在上述方法中,我如何告诉.net核心,在SendByEmail方法中,我需要一个EmailSender类的实例,在SendBySMS方法中,我需要SMSSender类的实例。我已经将其添加到启动类中,但是它显然总是创建EmailSender类的实例:

services.AddTransient<IMessageSender, EmailSender>();

1 个答案:

答案 0 :(得分:1)

当前您拥有:

public interface IMessageSender
{
    Task SendMessageAsync(parameters);
}

和两个实现该接口的类。确实可以,但是我建议对该方法进行一些微调。保留IMessageSender,并添加两个新接口:

public interface IEmailSender : IMessageSender
{
}

public interface ISMSSender : IMessageSender
{
}

为什么这样做?好了,它现在允许您注入感兴趣的特定发件人(此控制器要发送电子邮件,该控制器要发送SMS)。

另外,由于它们都从IMessageSender继承,因此带有一些IoC容器(例如Autofac-我尚未对它们进行全部测试),因此您还可以注入IMessageSender的集合(即{{1} })-并非总是有效,但是如果您要调用所有消息发件人(即此 SMS),则可能很有用。通过电子邮件发送)。如果这没有用-没问题,请完全删除IEnumerable<IMessageSender>(并将定义接口的方法移到IMessageSenderIEmailSender中)。

现在,更改您的类以实现新接口:

ISMSSender

,并针对与容器的两个接口注册您的类。 使用Autofac就像public class EmailSender : IEmailSender { } public class SMSSender : ISMSSender { }

看看您现有的代码,我建议采用以下解决方案:

AsImplementedInterfaces

然后将您的控制器更改为:

services.AddTransient<IEmailSender, EmailSender>();
services.AddTransient<ISMSSender, SMSSender>();
services.AddTransient<IMessageSender, EmailSender>();
services.AddTransient<IMessageSender, SMSSender>();