如何在电子邮件和短信类中使用DI [英] How can I use DI with Email and SMS classes

查看:162
本文介绍了如何在电子邮件和短信类中使用DI的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有这个接口:

public interface IMessageSender
{
    Task SendMessageAsync(parameters);
}

此类:

public class EmailSender : IMessageSender
{
}

public class SMSSender : IMessageSender
{
}

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

In my controller I have used them like this:

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

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

And I have two methods in this controller:

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

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

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

In the above methods, how can I tell to the .net core that in the SendByEmail method, I need an instance of EmailSender class and in the SendBySMS method, I need an instance of SMSSender class. I have already added this to my startup class, but it clearly create an instance of EmailSender class always:

services.AddTransient<IMessageSender, EmailSender>();


推荐答案

当前您拥有:

public interface IMessageSender
{
    Task SendMessageAsync(parameters);
}

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

and two classes that implement that interface. That does work, but I'd suggest a slight tweak to that approach. Keep IMessageSender, and add two new interfaces:

public interface IEmailSender : IMessageSender
{
}

public interface ISMSSender : IMessageSender
{
}

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

Why do this? Well, it now allows you to inject in a specific sender that you are interested in (this controller wants to send emails, that controller wants to send SMS).

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

Additionally, since they both inherit from IMessageSender, with some IoC containers (e.g. Autofac - I haven't tested them all) you could also inject a collection of IMessageSender (i.e. IEnumerable<IMessageSender>) - this is not always useful, but it can be useful if you want to invoke all of the message senders (i.e. SMS this and email this). If this is not useful - not a problem, remove IMessageSender altogether (and move the methods that define the interface into both IEmailSender and ISMSSender).

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

Now, change your classes to implement your new interfaces:

public class EmailSender : IEmailSender
{
}

public class SMSSender : ISMSSender
{
}

并使用容器的两个接口注册您的类。 使用Autofac就像 AsImplementedInterfaces

and register your classes against both interfaces with your container. With Autofac that would be something like AsImplementedInterfaces.

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

Looking at your existing code, I'd suggest the below solution:

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

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

Then change your controller to:

public MyController(IEmailSender emailSender, ISMSSender smsSender)

这篇关于如何在电子邮件和短信类中使用DI的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆