Entering a registrar with constructor dependencies

I am trying to refactor some code to use .NET Core dependency injection through the mapping services in startup.cs. I would like to introduce an IRequestDatabaseLogger here instead of updating it. However, this requires context in the constructor. How can i achieve this? Is this even possible without a DI framework, or even then?

public class ActionFilter : ActionFilterAttribute { public override void OnActionExecuting(ActionExecutingContext context) { var requestDatabaseLogger = new RequestDatabaseLogger(context); long logId = requestDatabaseLogger.Log(); context.HttpContext.AddCurrentLogId(logId); base.OnActionExecuting(context); } } 
+5
source share
3 answers

However, this requires context in the constructor.

Providing the construction of application components depends on the runtime data - this is an anti-pattern, as described here . This article describes how to solve these problems in general.

In your case, this probably means that your component should depend on the ASP.NET Core IHttpContextAccessor abstraction, and this is the template described in the reference article.

Alternatively, as described in the article, you can pass the necessary runtime data to the log using the Log method.

+8
source

You must use TypeFilter to achieve this and wrap the filter, which has a dependency (in this case, on the log or context) inside the filter. I am showing a detailed example of this in an MSDN article in basic ASP.NET filters . Related source code here (see ValidateAuthorExists filter).

Here's what might appear in your scenario:

 public class MyFilterAttribute : TypeFilterAttribute { public MyFilterAttribute():base(typeof(MyFilterImpl)) { } private class MyFilterImpl : IAsyncActionFilter { public MyFilterImpl( *inject dependencies here*) {} } } 

Here's how you can use attributes in .NET Core while still inserting dependencies in the main action filter. I will also talk about this in my upcoming ASP.NET Core Quickstart course on DevIQ.com (look for it later this month).

+2
source

Insert a RequestDatabaseLoggerFactory into the constructor, which you can use to create an instance of RequestDatabaseLogger .

 public interface IRequestDatabaseLoggerFactory { IRequestDatabaseLogger Create(ActionExecutingContext context); } public class RequestDatabaseLoggerFactory : IRequestDatabaseLoggerFactory { public IRequestDatabaseLogger Create(ActionExecutingContext context) { return new RequestDatabaseLogger(context); } } public class ActionFilter : ActionFilterAttribute { public ActionFilter(IRequestDatabaseLoggerFactory factory) { _factory = factory; } private readonly IRequestDatabaseLoggerFactory _factory; public override void OnActionExecuting(ActionExecutingContext context) { var requestDatabaseLogger = _factory.Create(context); long logId = requestDatabaseLogger.Log(); context.HttpContext.AddCurrentLogId(logId); base.OnActionExecuting(context); } 

}

0
source

Source: https://habr.com/ru/post/1263863/


All Articles