Search code examples
c#prismunity-container.net-framework-versionef-core-2.2

Register EF Core in Prism in full .NET Framework


I want to use EF.Core 2.2.6 in a .Net Framework (4.6.2) project. I have created a separate project for the database.

I want to register the DbContext in the main project using dependency injection over the Prism framework (Unity).

var optionsBuilder = new DbContextOptionsBuilder<DbContext>();
optionsBuilder.UseSqlite(@"Data Source=CustomerDB.db");
containerRegistry.GetContainer().RegisterType<DbContext, CrossSettingContext>();
containerRegistry.GetContainer().RegisterType<DbContext>(new InjectionConstructor(optionsBuilder));

The database context:

public  class CrossSettingContext : DbContext
{
    private static Action<DbContextOptionsBuilder> onConfigure;
    #pragma warning restore 649

    public CrossSettingContext(DbContextOptions<CrossSettingContext> options) : base(options)
    {
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.EnableSensitiveDataLogging(true);
        onConfigure?.Invoke(optionsBuilder);
    }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Setting>().Map();
    }
}

I get the following exception. The question is if I am using the right approach for registering EF Core.

System.InvalidOperationException: "No member matching data has been found.

Error in: RegisterType(Invoke.Constructor(Microsoft.EntityFrameworkCore.DbContextOptionsBuilder`1[Microsoft.EntityFrameworkCore.DbContext]))

I found this question -> but I need EF Core 2.2.6 and not Entity Framework 6.0


Solution

  • The answer from Haukinger is partially correct, but missing quite a bit of important information.

    What you will want to do something like:

    var optionsBuilder = new DbContextOptionsBuilder<CrossSettingContext>();
    optionsBuilder.UseSqlite( @"Data Source=CustomerDB.db" );
    

    However you do not need anything Container Specific AT ALL here. All you really need is:

    containerRegistry.RegisterInstance(optionsBuilder.Options);
    

    You do not actually need to register the CrossSettingContext if you want a new instance each time it's resolved. Though you could do the following if you want a singleton:

    containerRegistry.RegisterSingleton<CrossSettingContext>();
    

    When you want to use it you can just inject the context in your ViewModel/Services like:

    public class ViewAViewModel
    {
        public ViewAViewModel(CrossSettingContext context)
        {
            // Do Stuff
        }
    }