1

I have a derived class of DbContext, called NavigationContext, that looks like this:

public class NavigationContext : DbContext
{
    private readonly IConfiguration _configuration;

    public NavigationContext(DbContextOptions<NavigationContext> options, IConfiguration configuration) : base(options)
    {
        _configuration = configuration;
    }
    //DbSets here ...

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        if (!optionsBuilder.IsConfigured)
        {
            optionsBuilder.UseSqlServer(_configuration.GetConnectionString("NavigationLoggingDatabase"));
        }
    }
}

The Configuration is registered to the DI container in Startup.cs, like this:

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
        services.AddDbContext<NavigationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("NavigationLoggingDatabase")));
        services.AddSingleton(_ => Configuration);
    }

My question is what do I send to the NavigationContext constructor?

    public int Add(TEntity item)
    {
        using (NavigationContext context = new NavigationContext(_contextOptionsBuilder.Options, ???))
        {
            context.Set<TEntity>().Add(item);
            context.SaveChanges();
            return item.Id;
        }
    }
2
  • 1
    You don't use new NavigationContext(...) at all, you're completely missing the point of DI if you do that. Commented Jan 16, 2019 at 22:25
  • Check out the documentation Commented Jan 17, 2019 at 0:11

2 Answers 2

2

That's not how you do DI (Dependency Injection). Whenever you see the new keyword for a service, you have to know it's wrong.

First, you don't have to pass in anything to the DbContext, that OnConfiguring override shouldn't be there as you are not using it. This call takes care of that configuration:

services.AddDbContext<NavigationContext>(options => options.UseSqlServer(Configuration.GetConnectionString("NavigationLoggingDatabase")));

Secondly, you don't use using with injected dependencies, so:

public int Add(TEntity item)
{
    _context.Set<TEntity>().Add(item);
    _context.SaveChanges();
    return item.Id;
}

And, for this to work:

public class SomeController : Controller
{
    private readonly NavigationContext _context;

    public SomeController(NagivationContext context)
    {
        _context = context;
    }
}

And, as a last advice, you should really, really, use the asynchronous versions of the Entity Framework Core methods as much as possible:

public async Task<int> Add(TEntity item)
{
    _context.Set<TEntity>().Add(item);
    await _context.SaveChangesAsync();
    return item.Id;
}
Sign up to request clarification or add additional context in comments.

2 Comments

To play devil's advocate, why the async versions of EF core methods?
@Riddari Very short version: You always want to free the Threads taken by ASP.NET Core as much and as fast as possible. Using the async version here means the Thread can go serve another user while the DB responds.
2

You don't use new NavigationContext(...) at all, you're completely missing the point of dependency injection if you do that. Instead you should be injecting the context into the class that needs it. For example, if you need it directly in your controller, that would look something like this:

public class FunkyController : Controller
{
    private readonly NavigationContext _nagivationContext;

    public FunkyController(NagivationContext nagivationContext)
    {
        //Context is injected into the constructor of the controller
        _nagivationContext = nagivationContext;
    }

    public int Add(TEntity item)
    {
        _nagivationContext.Set<TEntity>().Add(item);
        _nagivationContext.SaveChanges();
        return item.Id;
    }
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.