Lukas Hieronimus Adler
Lukas Hieronimus Adler

Reputation: 1094

Dependency Injection with Database-Context. How to get Database-Context in a normal Class

I have configured my .net-core 2.1 service with a database-context in the start-up method.

 services.AddDbContext<DatabaseContext>(options => options.UseSqlServer(Configuration.GetConnectionString(nameof(DatabaseContext))));

Now i could do the following to get my database-context in my controller:

var context = serviceProvider.GetService<DatabaseContext>();

This works very well. But how could i access the Database-Context in a normal class something like this sould be done:

public class MyAccessClass{

    public MyAccessClass(){

        //Access the ServiceProvider or get the Database-Context class anywhere else
    }
}

I don't want to pass the database-context object through the constructor or to initialize the DatbaseContext Class again.

Thanks for your help.

Upvotes: 1

Views: 2734

Answers (1)

Max
Max

Reputation: 137

You should take your dependencies through the constructor, preferrably an interface, e.g. IDatabaseContext, but code sample below based on your code. If you add MyAccessClass as a service, e.g. services.AddTransient<MyAccessClass>(), and then use dependency injection in your controller, the database context would be automatically injected in the constructor by the default IoC container in ASP.NET Core.

You shouldn't have it rely on IServiceProvider, the reasoning is that your class wants to make no assumption of implementations, it just needs the database context. Having it rely on IServiceProvider would assume this context, and any possible future dependencies, comes from the IoC in ASP.NET Core which may not be the case (what if you just want to release this as a class library later on?). It would make the MyAccessClass class hard to test and use outside of a controller.

You say in your comment:

"...or get the Database-Context class anywhere else"

That anywhere else is completely flexible by simply accepting the context into the constructor since your class doesn't know where anywhere else is but whatever is creating your class does know!

Example of DI in ASP.NET Core

Take context as a dependency through constructor

public class MyAccessClass{
    private readonly DatabaseContext databaseContext;
    public MyAccessClass(DatabaseContext databaseContext) {
        this.databaseContext = databaseContext;
    }
}

Add as service

public void ConfigureServices(IServiceCollection services)
{
    services.AddTransient<MyAccessClass>();
}

Inject into a controller

public class MyController : Controller
{
    private readonly MyAccessClass myAccessClass;
    //Happily injected through DI
    public MyController(MyAccessClass myAccessClass)
    {
        this.myAccessClass = myAccessClass;
    }
}

Or inject straight into an action

public class MyController : Controller
{
    public MyController()
    {
    }

     public IActionResult MyAction([FromServices] MyAccessClass myAccessClass)
     {

     }
}

Upvotes: 1

Related Questions