【发布时间】:2019-01-28 21:15:19
【问题描述】:
我有这个界面:
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>();
【问题讨论】:
-
不需要IMessageSender就不用注册了。仅当您需要“发送它,我不在乎如何”之类的抽象时。当您定义 IEmailSender 时,您的意思是“通过电子邮件发送”。您定义的每个接口背后都应该有具体的意图。在某个时间点 IEmailSender 可以接收其他参数并与 IMessageSender 完全分离。
-
我建议这种方法的原因是很多人的诱惑是'这两个类做同样的事情,所以给他们一个公共接口'。但通常使用错误的方式思考它的接口。在考虑接口时,主要关注调用者。 调用者想要什么?如果来电者想发送电子邮件 - 给他们一个界面来做到这一点。如果他们想发送短信 - 给他们一个界面来做到这一点。他们不关心你的抽象——他们关心的是发送电子邮件或短信。
标签: c# asp.net-core dependency-injection .net-core