我们正在重新设计一个 ASP.NET MVC 应用程序,该应用程序在助手中具有业务逻辑。我们希望它具有 DI 服务(通过依赖注入传递给控制器)。
我们有 2 个概念不明白如何处理 DI 服务:
缺少构造函数的示例
我们可以有一个在
Startup.cs
中启动的邮件服务,具有基本配置,如 SMTP server
、SMTP port
等。它不会设置 From:
用户,因为在应用程序中 From:
用户是不同的,所以它需要作为参数传递,比如
_mailService.Send(from, to, subject, message)
但是如果我们现在在助手中做这样的事情呢?
MailHelper mailhelper = new MailHelper(from, to);
mailhelper.Send(subject1, message1);
mailhelper.Send(subject2, message2);
mailhelper.Send(subject3, message3);
如何在 DI 中做到这一点?我怀疑你能做到:
_mailService.NewBatch(from, to);
_mailService.Send(subject1, message1);
_mailService.Send(subject2, message2);
_mailService.Send(subject3, message3);
我不明白
请帮我理解:
如果在上面的示例中忘记调用
_mailService.NewBatch(from, to)
怎么办,您需要自己在服务中跟踪这一情况吗?如果有人在没有先调用 Send()
的情况下使用 NewBatch()
,你可能会抛出异常,但使用帮助器和构造函数你不会忘记。而且由于这些服务的使用寿命很长,因此它们仍然可以保留旧的 from
和 to
。
如果您同时拥有助手和 DI 服务。您是否将所有 DI 服务作为参数传递到助手的构造函数中?即使对于助手内部逻辑深处所需的服务(例如日志记录)?
描述的第一个选项,
_mailService.Send(from, to, subject, message)
在这种情况下是最简单的,因为它清楚地区分了运行时值和服务。我的建议是像这样设计 API。
如果由于遗留原因,你不能这样做,那么用这样的 API 编写一个 Decoraptor 并使用它。您可以在不太适合您的 API 上实现 Decoraptor,例如
MailHelper
示例。
如果出于某种我无法想象的原因,这是不可能的,定义一个抽象工厂,从
IMailHelper
和from
创建一个to
对象。
我想不出像
NewBatch
建议那样定义 API 的充分理由。它完全具有 OP 中概述的问题,并且没有缓解质量。