.NET API의 특성을 사용한 종속성 주입
종속성 주입은 아마도 현재 .NET에서 제공하는 최고의 기능 중 하나일 것입니다. 당신이 그것을 사용하지 않을 가능성은 전혀 없습니다. 따라서 당신이 나와 같다면 당신이 만드는 모든 구현에 그것을 추가하고 싶을 것입니다.
공식 Microsoft의 문서에 따른 필터:
ASP.NET Core의 필터를 사용하면 요청 처리 파이프라인의 특정 단계 전후에 코드를 실행할 수 있습니다.
내장 필터는 다음과 같은 작업을 처리합니다.
- 승인, 사용자가 승인되지 않은 리소스에 대한 액세스를 방지합니다.
- 응답 캐싱, 캐시된 응답을 반환하기 위해 요청 파이프라인을 단락시킵니다.
교차 편집 문제를 처리하기 위해 사용자 정의 필터를 만들 수 있습니다. 교차 편집 문제의 예로는 오류 처리, 캐싱, 구성, 권한 부여 및 로깅이 있습니다. 필터는 코드 중복을 방지합니다.
저는 API로 많은 작업을 하고 있으며 모든 단일 요청 또는 거의 모든 요청을 실행해야 하는 몇 가지 작업이 있습니다. 따라서 이상적으로 우리가 원하는 것은 API를 사용하여 작업하는 것입니다…. 종속성 주입!
하지만 때로는 약간의 트릭일 수도 있습니다. ActionAttribute에서 상속하려는 경우 원하는 대로 작동하지 않으므로 OnActionExecutionAsync를 재정의할 때 작업을 수행할 수 있는 TypeFilterAttribute로 작업해야 합니다.
저는 보통 로깅을 수행하기 위해 이 필터를 생성하므로 이를 예로 사용하겠습니다.
/// <summary>
/// LoggedQueryAttribute class
/// </summary>
public class LoggedQueryTypeFilterAttribute : TypeFilterAttribute
{
/// <summary>
/// Constructor for <see cref="LoggedQueryTypeFilterAttribute"/>
/// </summary>
public LoggedQueryTypeFilterAttribute() : base(typeof(LoggedQueryFilter))
{
}
/// <summary>
/// LoggedQueryFilter class
/// </summary>
private class LoggedQueryFilter : IAsyncActionFilter
{
/// <summary>
/// <see cref="_loggingService"/> object
/// </summary>
private readonly LoggingService _loggingService;
/// <summary>
/// Constructor for <see cref="LoggedQueryFilter"/>
/// </summary>
/// <param cref="LoggingService" name="loggingService">Parameter for loggingService</param>
public LoggedQueryFilter(LoggingService loggingService)
{
_loggingService = loggingService;
}
/// <summary>
/// OnActionExecutionAsync
/// </summary>
/// <param cref="ActionExecutingContext" name="context">Parameter for context</param>
/// <param cref="ActionExecutionDelegate" name="next">Parameter for next</param>
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
// Get properties
var properties = (Request)context.ActionArguments.First().Value!;
// Get call from context
var call = context.HttpContext.Request.Path.Value!;
// Logging
_loggingService.LogCustomEvent(call);
// Continue call
await next();
}
}
}
논리는 매우 간단합니다. context.ActionArguments.First().Value를 사용하여 context 객체에 액세스하여 본문을 얻고, 또한 context.HttpContext.Request.Path.Value를 사용하여 메서드 호출을 수행합니다.
그런 다음 서비스에서 메서드를 호출합니다. 이 경우에는 _loggingService.LogCustomEvent(call)입니다.
그런 다음 파이프라인이 계속되어야 하므로 await next();를 호출해야 합니다.
이는 속성에 대한 것이므로 실제로 이 속성을 메소드에 포함해야 합니다.
[LoggedQueryTypeFilterAttribute]
public ActionResult<string> TestFilter()
{
return Ok("Hello world!");
}
재미있게 보셨기를 바라며, 궁금하신 점이나 연락하고 싶으신 점이 있으시면 주저하지 마시고 연락주세요!