Add-Migration without parameterless DbContext and DbContextFactory constructor

c# entity-framework-6

Question

My application has no parameterless constructor at my DbContext implementation and I don't like to provide a parameterless constructor to a IDbContextFactory<> implementation.

The reason is I want to keep control where the DbContext points to. That's why all my constructors will ask for the ConnectionStringProvider.

public class MyDbContext : DbContext
{
    internal MyDbContext(IConnectionStringProvider provider) : base(provider.ConnectionString) {}
}

and

public class MyContextFactory : IDbContextFactory<MyDbContext>
{
    private readonly IConnectionStringProvider _provider;
    public MyContextFactory(IConnectionStringProvider provider)
    {
        _provider = provider;
    }
    public MyDbContext Create()
    {
        return new MyDbContext(_provider.ConnectionString);
    }
}

I definitely don’t want to add a default constructor! I already did that and it crashed on production because of the wrong connection strings inside the wrong App.config or assuming a default connection string like the default constructor of DbContext does. I would like use the same infrastructure on

  • Debug/Relase (and only inject a different IConnectionStringProvider)
  • Calling Add-Migration script
  • Running DbMigrator.GetPendingMigrations()

Currently I get some of those messages:

The context factory type 'Test.MyContextFactory' does not have a public parameterless constructor. Either add a public parameterless constructor, create an IDbContextFactory implementation in the context assembly, or register a context factory using DbConfiguration.

---UPDATE---

This might be a duplicate of How do I inject a connection string into an instance of IDbContextFactory<T>? but it has no solution. I explain why:

  • I always use Add-Migration with connection string, so how can I provide a DbContext or IDbContextFactory<> that consumes it? Instead of parameterless constructors?

    Add-Migration MyMigration -ConnectionStringName "MyConnectionString"

  • The same problem here: I use DbMigrator.GetPendingMigrations() which also asks for parameterless DbContext or IDbContextFactory<> implementations.

As far as I understand EntityFramework violates encapsulation by implying default constructors and causes temporal coupling which is not fail-safe. So please propose a solution without parameterless constructors.

1
5
5/23/2017 12:10:18 PM

Popular Answer

Create a Migrate Initializer that takes a connection string as constructur parameter then you could pass it to the Migration Constructor so it can use that connection string

 public class MigrateInitializer : MigrateDatabaseToLatestVersion<MyContext, Configuration>
    {
        public MigrateInitializer(string connectionString) : base(true, new Configuration() { TargetDatabase=new  System.Data.Entity.Infrastructure.DbConnectionInfo(connectionString,"System.Data.SqlClient") })
        {
        }

    }

The pass it to the MigrateInitializer

public class MyContext : DbContext { public MyContext(string connectionString) : base(connectionString) { Database.SetInitializer(new MigrateInitializer(connectionString)); }

}

Thats it now the migration will use the connection string your provided

1
12/24/2018 3:02:20 PM


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