Note that there are some explanatory texts on larger screens.

plurals
  1. POHow do I inject a connection string into an instance of IDbContextFactory<T>?
    primarykey
    data
    text
    <p>I'm using Entity Framework 5 with Code First Migrations. I have a <code>DataStore</code> class which derives from <code>DbContext</code>:</p> <pre><code>public class DataStore : DbContext, IDataStore { public int UserID { get; private set; } public DataStore(int userId, string connectionString) : base(connectionString) { UserID = userId; } public virtual IDbSet&lt;User&gt; Users { get; set; } // Rest of code here } </code></pre> <p>And a factory class which creates instances of the <code>DataStore</code> class:</p> <pre><code>public class DataStoreFactory : Disposable, IDataStoreFactory { private DataStore _database; private int _userId; private string _connectionString; public DataStoreFactory(int userId, string connectionString) { _userId = userId; _connectionString = connectionString; } public IDataStore Get() { _database = new DataStore(_userId, _connectionString); return _database; } protected override void DisposeCore() { if (_database != null) _database.Dispose(); } } </code></pre> <p>These classes have their constructor parameters injected at runtime with <a href="http://unity.codeplex.com/">Unity</a>. So far so good, everything works great! </p> <p>The problem arises when we get to migrations: because my <code>DataStore</code> context class doesn't have a default constructor, I need to supply an implementation of <code>IDbContextFactory&lt;T&gt;</code> so that Code First Migrations can instantiate it:</p> <pre><code>public class MigrationDataStoreFactory : IDbContextFactory&lt;DataStore&gt; { public DataStore Create() { // Need to inject connection string so we can pass it to this constructor return new DataStore(0, "CONNECTION_STRING_NEEDED_HERE"); } } </code></pre> <p>The issue is that I can't figure out how I can inject the connection string into this class. I can't create a new constructor with a connection string parameter like this: </p> <pre><code>public class MigrationDataStoreFactory : IDbContextFactory&lt;DataStore&gt; { public string _connectionString { get; set; } public MigrationDataStoreFactory(string connectionString) { _connectionString = connectionString; } public DataStore Create() { return new DataStore(0, new DateTimeProvider(() =&gt; DateTime.Now), _connectionString); } } </code></pre> <p>If I do, I get the following exception thrown by Migrations at runtime: </p> <pre><code>[InvalidOperationException: The context factory type 'MigrationDataStoreFactory' must have a public default constructor.] System.Data.Entity.Infrastructure.DbContextInfo.CreateActivator() +326 System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType, DbProviderInfo modelProviderInfo, AppConfig config, DbConnectionInfo connectionInfo) +106 System.Data.Entity.Infrastructure.DbContextInfo..ctor(Type contextType) +52 System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration, DbContext usersContext) +202 System.Data.Entity.Migrations.DbMigrator..ctor(DbMigrationsConfiguration configuration) +66 System.Data.Entity.MigrateDatabaseToLatestVersion`2.InitializeDatabase(TContext context) +50 // Truncated stack trace, but you get the idea </code></pre> <p>Aside from that, this class is not instantiated by Unity anyway; it seems to just be called by convention by Code First Migrations somehow, so even if I could do that it wouldn't really help...</p> <p>Everything works fine if I hard-code the connection string in that method, but I don't want to do that, for obvious reasons.</p> <p>Can anyone help please?</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload