【问题标题】:common services in asp.net core with razor pages带有剃须刀页面的 asp.net 核心中的常用服务
【发布时间】:2019-05-29 05:56:55
【问题描述】:

作为参考,我有一个通用的BasePageModel,它继承了PageModel

我还有几项我会一直使用的服务:

  1. UserManager<AppUser> userManager
  2. IHttpContextAccessor httpContextAccessor
  3. IHostingEnvironment env

有没有办法总是注入这些,这样我就不必在每个 Razor 页面上为每个服务进行构造函数注入?

【问题讨论】:

  • 您根本不需要使用上下文访问器,因为您可以从 MVC 控制器和页面模型访问 HttpContext。至于用户管理器和托管环境,不,您必须正确注入它们。但是如果你发现自己经常使用它们,你应该考虑将一些逻辑从你的页面模型中移出。如果您解释一下您实际在做什么,我们或许可以提出替代方法。
  • @poke 感谢您的快速回复!在每个剃须刀页面上,我通常需要从HttpContext 访问某些内容,并确定该页面是在开发中还是在生产中加载的。似乎总是注射它们并不是很干燥。
  • 您将这些信息用于什么目的?展示替代的东西?也许您可以将该逻辑移到其他地方(例如,在标签助手中,例如已经存在的<environment> 标签助手)。通常,明确列出所有依赖项被认为是一种很好的风格,即使它感觉是多余的或样板式的。
  • “在开发/测试中,我不想在提交表单时发送结果和确认电子邮件”——然后​​考虑将其抽象为服务。例如,不要直接从您的页面模型发送电子邮件,而是让一些电子邮件服务负责发送邮件。然后,您可以跳过在该服务中发送邮件,或者在开发期间完全更换服务实现。所以页面模型不必承担这个责任,并且无论环境如何都保持不变。
  • 通常,您将有一个用于测试的 SMTP 服务器,该服务器将被配置为捕获所有外发电子邮件并将它们转发到某个内部收件箱。这样,您可以验证您的应用程序是否正常工作(不考虑当前配置的环境),同时可以防止意外电子邮件离开您的开发阶段。

标签: razor asp.net-core razor-pages


【解决方案1】:

通常,您可以使用_ViewImports.cshtml 定义要注入到每个视图中的服务。只需在此处添加您的视图注入,该服务将可用于每个视图。

但是,您不应该对您明确提及的三项服务中的任何一项执行此操作。首先,IHttpContextAccessor 是不必要的,因为您可以通过ViewContext.HttpContext 在您的视图中获取HttpContext。同样,IHostingEnvironment 也大多是不必要的,因为您可以使用 environment 标签助手:

<environment include="Development">
    <p>This is development.</p>
</environment>
<environment exclude="Development">
    <p>This is production.</p>
</environment>

对于UserManager&lt;AppUser&gt;,最好仅在您真正需要时才包含此类服务。如果您发现自己一遍又一遍地执行相同的逻辑需要此服务,请考虑创建标签助手或视图组件来封装该逻辑,以便您可以在多个地方使用它,而无需在视图中注入任何特殊内容。

最后,由于本次讨论的重点主要是关于在开发中不发送电子邮件,因此更好的方法是简单地将 SMTP 服务器换成开发中的本地服务器。有一个名为Papercut 的应用程序是开源和免费的,使开发中的发送/接收电子邮件变得轻而易举。默认情况下,它将绑定到 localhost:25,因此您只需将真实的 SMTP 连接换成它。例如,您可以在 appsettings.json 中创建一个部分,例如:

"Smtp": {
  "Host": "localhost",
  "Port": 25,
  "EnableSsl": false,
  "Username": "",
  "Password": ""
}

然后,在您的启动中:

services.AddSingleton(_ => {
    var config = Configuration.GetSection("Smtp").Get<SmtpConfig>();
    return new SmtpClient
    {
        Host = config.Host,
        Port = config.Port,
        EnableSsl = config.EnableSsl,
        Credentials = new NetworkCredential(config.Username, config.Password)
    };
});

然后,只需将SmtpClient 注入您的电子邮件服务,您就可以参加比赛了。在生产中,可以使用环境变量或 Azure Key Vault 来交换生产 SMTP 连接设置。最好不要为此使用 appsettings.json(或 appsettings.Production.json),因为您很可能不想将其提交到源代码管理中。

【讨论】:

    猜你喜欢
    • 2019-06-13
    • 2020-11-09
    • 2021-10-07
    • 2021-01-05
    • 2019-01-19
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多