我有这个界面:
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>();
答案 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>
(并将定义接口的方法移到IMessageSender
和IEmailSender
中)。
现在,更改您的类以实现新接口:
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>();