I'm trying to refactor some code to use .NET Core dependency injection via mapping services in startup.cs. I would like to inject an IRequestDatabaseLogger here instead of newing it up. However it requires the context in the constructor. How can I achieve this? Is it even possible without an 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);
}
}
However it requires the context in the constructor.
Letting the construction of application components depend on runtime data is an anti-pattern, as described here. That article describes how to solve these problems in general.
In your case this probably means that your component should depend on ASP.NET Core's IHttpContextAccessor
abstraction instead, which is a pattern described in the referenced article.
Alternatively, as described in the article, you can pass through the required runtime data to the logger using it's Log
method.
You should use the TypeFilter to achieve this, and wrap the filter that has the dependency (in this case on a logger or a context) inside of the filter. I show a detailed example of this in my MSDN Article on ASP.NET Core Filters. The related source code is here (look at the ValidateAuthorExists filter).
Here's what it might look like in your scenario:
public class MyFilterAttribute : TypeFilterAttribute
{
public MyFilterAttribute():base(typeof(MyFilterImpl))
{
}
private class MyFilterImpl : IAsyncActionFilter
{
public MyFilterImpl( *inject dependencies here*)
{}
}
}
This is how you can use attributes in .NET Core while still injecting dependencies into the underlying action filter. I also cover this in my upcoming ASP.NET Core Quickstart course on DevIQ.com (look for it end of this month).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With