如何在没有依赖项注入的情况下使用ILogger?

问题描述

.net核心项目。我正在使用azure应用程序见解进行记录。我在services.AddApplicationInsightsTelemetry();中添加了以下内容:在我的startup.cs中。在控制器和业务层中,我将通过依赖注入获得ILogger。但是我想出了一些不同的东西。我创建了ApiExceptionFilter,代码如下所示。

public class ApiExceptionFilter : ExceptionFilterattribute
    {  
        public override void OnException(ExceptionContext context)
        {
            ApiError apiError = null;
            if (context.Exception is ApiException)
            {
                // handle explicit 'kNown' API errors
                var ex = context.Exception as ApiException;
                context.Exception = null;
                apiError = new ApiError(ex.Message);

                context.HttpContext.Response.StatusCode = ex.StatusCode;
            }
            else if (context.Exception is UnauthorizedAccessException)
            {
                apiError = new ApiError("Unauthorized Access");
                context.HttpContext.Response.StatusCode = 401;

                // handle logging here
            }
            else if (context.Exception is NotImplementedException)
            {
                apiError = new ApiError("Not Implemented");
                context.HttpContext.Response.StatusCode = 401;

                // handle logging here
            }
            else if (context.Exception is ArgumentNullException)
            {
                apiError = new ApiError(string.Format("Parameter: {0} is required,it cannot be empty",(context.Exception as ArgumentNullException).ParamName));
                context.HttpContext.Response.StatusCode = 401;

                // handle logging here
            }
            else
            {
                // Unhandled errors
                var msg = context.Exception.GetBaseException().Message;
                string stack = context.Exception.StackTrace;
                apiError = new ApiError(msg);
                apiError.detail = stack;

                context.HttpContext.Response.StatusCode = 500;

                // handle logging here
            }

            // always return a JSON result
            context.Result = new JsonResult(apiError);

            base.OnException(context);
        }
    }

但是在这里我不能做类似的事情

private readonly ILogger _logger;
        public ApiExceptionFilter(ILogger logger)
        {
            _logger = logger;
        }

如果我做出上述更改,那么

  [ApiController]
    [ApiExceptionFilter] //here it asking for paramter ilogger
    public class MyController : ControllerBase

在上面的代码[ApiExceptionFilter]中,它将要求我传递ILogger参数。

我只是想知道在ApiExceptionFilter中添加ILogger的正确方法是什么。有人可以帮我吗任何帮助,将不胜感激。谢谢

解决方法

您可以使用以下方法添加例外过滤器:

[TypeFilter(typeof(ApiExceptionFilter))]

这将允许您的过滤器使用DI容器中的服务,因为框架会在请求时创建过滤器。

例如

public class ApiExceptionFilter : ExceptionFilterAttribute
{
    public ApiExceptionFilter(ILogger logger)
    {
        // Assign the logger to a field etc.
    }
}

您还可以使用[ServiceFilter(typeof(ApiExceptionFilter))]并将过滤器本身注册到DI容器中。

,

要在操作过滤器中使用DependencyInjection,您需要使用TypeFilterAttribute,

示例:

public class HandleExceptionAttribute : TypeFilterAttribute
{
        public HandleExceptionAttribute() : base(typeof(HandleExceptionPrivate))
        {
        }

        class HandleExceptionPrivate : ExceptionFilterAttribute
        {
            private readonly ILogger _logger;
            private readonly IHostingEnvironment _env;
          
            public HandleExceptionPrivate(ILoggerFactory logger,IHostingEnvironment env)
            {
                _logger = logger.CreateLogger("Exeption Filter");
                _env = env;
            }

            public override void OnException(ExceptionContext context)
            {
                _logger.LogError(Constants.LoggingEvents.EXCEPTION,context.Exception,"message");
               
                context.ExceptionHandled = true;
                context.Exception = null;
            }
        }
}