How to inject EntityFramework Core DbContext in Repository

autofac botframework c# entity-framework entity-framework-core

Question

Most of the examples online deal with asp.net and register their DbContext as part of their startup service registry.

I tried registering my DbContext like this

builder.RegisterType<MyContext>()
    .As<MyContext>()
    .InstancePerLifetimeScope();

builder.RegisterType<DealRepository>()
    .Keyed<IRepository<Deal>>(FiberModule.Key_DoNotSerialize)
    .As<IRepository<Deal>>()
    .SingleInstance();

builder.RegisterType<CardsDialog>()
    .As<IDialog<object>>()
    .InstancePerDependency();

But I'm getting this error

Inheritance security rules violated by type: 'System.Net.Http.WebRequestHandler'. Derived types must either match the security accessibility of the base type or be less accessible.

It's even more complicated as the actual MessageController.cs creates a new scope on Post

using (var scope = DialogModule.BeginLifetimeScope(Conversation.Container, activity))
{
    var dialog = scope.Resolve<IDialog<object>>();

    await Conversation.SendAsync(activity, () => dialog);

}

How should the registering be done?

EDIT: As suggested, using InstancePerRequest solved the problem. But I also have a Quartz jobs that runs every X seconds that also needs a repository.

builder.RegisterType<DealJob>()
    .AsSelf()
    .SingleInstance();

Unable to resolve the type 'BargainBot.Repositories.MyContext' because the lifetime scope it belongs in can't be located. The following services are exposed by this registration: - BargainBot.Repositories.MyContext

Details ---> No scope with a tag matching 'AutofacWebRequest' is visible from the scope in which the instance was requested. If you see this during execution of a web application, it generally indicates that a component registered as per-HTTP request is being requested by a SingleInstance()

Should I resolve a new DbContext manually at this point? Or maybe I should change the my repo's life cycle?

Edit2: Looks like I'm still getting this error even when removing the entire Quartz job registration.

1
4
3/5/2017 12:11:59 AM

Accepted Answer

I was wrong about the issue, it wasn't an IoC and DbContext issue. Seems like it was in the .NET platform itself

https://github.com/dotnet/corefx/issues/9846#issuecomment-274707732

Adding a redirect did the trick

  <dependentAssembly>
    <assemblyIdentity name="System.ComponentModel.TypeConverter" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
    <bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.0.0" />
  </dependentAssembly>
1
3/5/2017 12:30:45 AM

Popular Answer

I was having a similar issue and after a lot of back and forth the following code worked for me:

DbContext

 public class SalesDbContext : DbContext
{
    public SalesDbContext(DbContextOptions<SalesDbContext> options) : base(options)
    {
    }

    public DbSet<Domain.Product.Product> Products { get; set; }


    protected override void OnModelCreating(ModelBuilder builder)
    {
        // Configure database attributes
    }



}

Repository

 public class ProductRepository : IProductRepository
{
    private readonly SalesDbContext _db;

    public ProductRepository(SalesDbContext db)
    {
        _db = db;
    }


}

Autofac Module

 public class DefaultModule : Module
{
    protected override void Load(ContainerBuilder builder)
    {
        // Register Entity Framework
        var dbContextOptionsBuilder = new DbContextOptionsBuilder<SalesDbContext>().UseSqlServer("MyConnectionString");

        builder.RegisterType<SalesDbContext>()
            .WithParameter("options", dbContextOptionsBuilder.Options)
            .InstancePerLifetimeScope(); 

    }
}


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow