Sam
Sam

Reputation: 21

EF core DbContext with dependency injection

I've created an injectable dbcontext

Startup.cs:

    public void ConfigureServices(IServiceCollection services) {
        services.AddScoped<IUnitOfWork, UnitOfWork>();

        services.AddDbContext<DBContext>(options => options.UseSqlServer("Server=localhost;Database=mydb;Trusted_Connection=True;"));
    }

UnitOfWork:

 public class UnitOfWork : IUnitOfWork {
    private readonly DBContext _context;
    public UnitOfWork(DBContext context) {
        _context = context;
    }

The injection working fine in the controller:

  public class UserController : ControllerBase {
    private readonly IUnitOfWork unitOfWork;
    public UserController(IUnitOfWork unitOfWork) {
        this.unitOfWork = unitOfWork;
    }
  }

How can I create custom class that takes IUnitOfWork in the constructor and call it from main program?

CustomClass :

  public class CustomClass {
    private readonly IUnitOfWork unitOfWork;
    public CustomClass(IUnitOfWork unitOfWork) {
        this.unitOfWork = unitOfWork;
    }
}

Main program:

    public class Program {
    public static void Main(string[] args) {
        var unitOfWork=new UnitOfWork()  // Here I don't want to pass new DBContext I want to reach the same injected DBContext 
        var customClass =new CustomClass (unitOfWork);

    }
}

Upvotes: 1

Views: 7063

Answers (3)

Serge
Serge

Reputation: 43860

I would try something like this:

public class Program {
    public static void Main(string[] args) {
    
    var optionsBuilder = new DbContextOptionsBuilder<DbContext>();
    optionsBuilder.UseSqlServer(connectionstring);

using(DbContext dbContext = new DbContext(optionsBuilder.Options))
{
          var unitOfWork=new UnitOfWork(dbContext)  
        var customClass =new CustomClass (unitOfWork);
       .....

    }
}
}

Upvotes: 0

What you can do is just add your class to the dependecy injection container and inject it into your constructor, you wouldn't need to inject the IUnitOfWork in you controller.

services.AddScoped<CustomClass>();

and then in your constroller constructor

public class UserController : ControllerBase {
  private readonly CustomClass _CustomClass;
  public UserController(CustomClass customClass) {
      _CustomClass = customClass;
  }
}

after that you are able to use this class in your class methods

Upvotes: 0

Yehor Androsov
Yehor Androsov

Reputation: 6152

Firstly, move out your code from ConfigureServices to some shared library that can be used both by Web and Console project. Create extension method to configure all your services.

using Microsoft.Extensions.DependencyInjection;

namespace ConsoleApp13
{
    public static class ConfigureServicesExtensions
    {
        public static void ConfigureMyServices(this IServiceCollection serviceCollection)
        {
            serviceCollection.AddDbContext<ApplicationDbContext>();

            serviceCollection.AddScoped<IUnitOfWork, UnitOfWork>();
            serviceCollection.AddScoped<CustomClass>();
        }
    }
}

This is how your Console app will look like

using Microsoft.Extensions.DependencyInjection;

namespace ConsoleApp13
{
    class Program
    {
        static void Main(string[] args)
        {
            var serviceCollection = new ServiceCollection();

            serviceCollection.ConfigureMyServices();

            using var serviceProvider = serviceCollection.BuildServiceProvider();
            using var scope = serviceProvider.CreateScope();

            var myService = scope.ServiceProvider.GetService<CustomClass>();
        }
    }
}

And your web project

public void ConfigureServices(IServiceCollection services)
{
    services.ConfigureMyServices();
}

Upvotes: 4

Related Questions