Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dependency injection with constructor parameter in .net core

I see a lot of code examples on how to use DI in .NET Core, however none of them use constructor parameters.

For example:

  • Create Authorization Service
  • Inject the current HTTP header(X-Api-Key) in constructor
  • In the implementation check if I have access

Here I need to not only use DI on my IAuthorizationService but also inject the token in the constructor. I know how to do it in Ninject, however have no experience in .NET Core DI.

Here is what I have as an example.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc();
    services.AddEntityFrameworkSqlite();
    services.AddDbContext<MainDbContext>();
    services.AddScoped<IAuthorizationService, AuthorizationService>(); // Inject current HttpContext header value as a constructor?
}
like image 833
Stan Avatar asked Aug 01 '16 20:08

Stan


People also ask

What is constructor dependency injection?

Dependency injection (DI) is a process whereby objects define their dependencies, that is, the other objects they work with, only through constructor arguments, arguments to a factory method, or properties that are set on the object instance after it is constructed or returned from a factory method.

How does .NET Core support dependency injection?

ASP.NET Core supports the dependency injection (DI) software design pattern, which is a technique for achieving Inversion of Control (IoC) between classes and their dependencies. For more information specific to dependency injection within MVC controllers, see Dependency injection into controllers in ASP.NET Core.

Can you inject dependency through private constructor?

To answer your question, there is no way. by definition, private constructors are inaccessible by other classes.

Is it difficult to inject dependency by constructor?

Frameworks that apply the Constrained Construction anti-pattern can make using Constructor Injection difficult. The main disadvantage to Constructor Injection is that if the class you're building is called by your current application framework, you might need to customize that framework to support it.


1 Answers

I usually flow such values through a service where the data is set in a piece of middleware. For example:

An accessor class which can be injected:

public class ApiKeyAccessor
{
    public string ApiKey { get; set; }
}

And a middleware which sets the API key at the beginning of the request:

public class ApiKeyMiddleware
{
    private readonly RequestDelegate _next;

    public ApiKeyMiddleware(RequestDelegate next)
    {
        _next = next;
    }

    public Task Invoke(HttpContext context, ApiKeyAccessor apiKeyAccessor)
    {
        StringValues key;
        if (context.Request.Headers.TryGetValue("X-Api-Key", out key))
        {
            apiKeyAccessor.ApiKey = key;
            return _next(context);
        }

        // todo: throw exception, etc..
    }
}

Now all we have to is add the ApiKeyAccessor to the DI container with a scoped lifetime and add the ApiKeyMiddleware to the request execution pipeline, preferably as soon as possible.

When configured correctly, we can inject the ApiKeyAccessor instance in controllers or services:

public class AuthorizationService
{
   private readonly string _apiKey;

   public AuthorizationService(ApiKeyAccessor apiKeyAccessor)
   {
      _apiKey = apiKeyAccessor.ApiKey;
   }
}
like image 63
Henk Mollema Avatar answered Sep 28 '22 07:09

Henk Mollema