繁体   English   中英

Asp.net Core获取依赖注入实例

[英]Asp.net Core get instance of Dependency Injection

我在Startup.cs中添加一个全局错误处理程序过滤器,如下所示:

services.AddMvc(o =>
{
    o.Filters.Add(new GlobalExceptionFilter());
});

但是,我需要传递我的电子邮件服务,该服务也正在注入。 如何从过滤器中的这些服务中检索它?

public class GlobalExceptionFilter : IExceptionFilter
{
    private readonly IEmailService _emailService;

    public GlobalExceptionFilter()
    {
    }

    public void OnException(ExceptionContext context)
    {

    }
}

我曾经能够使用DependencyResolver类在MVC5中做到这一点。 有没有办法做到这一点? 还是我有办法在启动中强制实例化服务,以便可以将其作为构造函数的一部分传递?

我尝试在服务中查找它,然后查看ImplementationInstance,但是此时它为null,所以我无法从那里获取它。 另外请记住,我的EmailService需要IOptions<Settings>参数,以便它可以获取所需的电子邮件设置。

您可以使用构造函数注入。

public class GlobalExceptionFilter : IExceptionFilter
{
    private readonly IEmailService emailService;
    public GlobalExceptionFilter(IEmailService emailService)
    {
        this.emailService = emailService;
    }
    public void OnException(ExceptionContext context)
    {
       //do something with this.emailService
    }
}

但是您必须更改在ConfigureServices方法中注册全局过滤器的方式。 您应该使用带有类型的Add重载

services.AddMvc(o =>
{
    o.Filters.Add(typeof(GlobalExceptionFilter));
});

另一个选择是,通过在HttpContext.RequestServices上调用GetService方法来显式解决OnException方法内部的依赖关系。

using Microsoft.Extensions.DependencyInjection;

public void OnException(ExceptionContext context)
{
    var emailService = context.HttpContext.RequestServices.GetService<IEmailService>();
    // use emailService
} 

但是第一种方法应该没问题。 让框架为您解决它,然后注入到构造函数中,而不用尝试这样做。

我认为,全局异常处理程序的最佳实践实际上是为其创建自定义中间件步骤。 文档中

异常过滤器非常适合捕获MVC操作中发生的异常,但它们不像错误处理中间件那样灵活。 一般情况下,最好使用中间件,并且仅在需要根据所选择的MVC操作不同地进行错误处理的地方使用过滤器。

然后,您在ConfigureServices方法中注册类:

services.AddTransient<IEmailService, EmailService>();

然后在您的Configure方法中,注册您的客户全局异常处理程序。 您将希望这是您在Configure方法中要做的第一件事,这样您就可以在其他中间件中捕获其后的所有异常。

app.UseMiddleware<MyGlobalExceptionHandler>();

您注册的所有服务都将对您的中间件构造函数可用,如下所示:

public sealed class MyGlobalExceptionHandler
{
    private readonly RequestDelegate _next;
    private readonly IEmailService _emailService;

    public NlogExceptionHandler(
        RequestDelegate next,
        IEmailService emailService)
    {
        _next = next;
        _emailService = emailService;
    }

    public async Task Invoke(HttpContext context)
    {
        try
        {

            await _next(context);
        }
        catch (Exception ex)
        {
            try
            {
                _emailService.SendEmail(ex.ToString());
            }
            catch (Exception ex2)
            {
                //Its good practice to have a second catch block for simple logging in case the email fails too
            }

            throw;
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM