【发布时间】:2013-09-15 01:58:57
【问题描述】:
我正在使用 Entity Framework 5 和 Code First 迁移。我有一个派生自DbContext 的DataStore 类:
public class DataStore : DbContext, IDataStore
{
public int UserID { get; private set; }
public DataStore(int userId, string connectionString) : base(connectionString)
{
UserID = userId;
}
public virtual IDbSet<User> Users { get; set; }
// Rest of code here
}
还有一个创建DataStore 类实例的工厂类:
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();
}
}
这些类的构造函数参数在运行时注入Unity。到目前为止一切顺利,一切正常!
当我们开始迁移时,问题就出现了:因为我的DataStore 上下文类没有默认构造函数,我需要提供IDbContextFactory<T> 的实现,以便 Code First Migrations 可以实例化它:
public class MigrationDataStoreFactory : IDbContextFactory<DataStore>
{
public DataStore Create()
{
// Need to inject connection string so we can pass it to this constructor
return new DataStore(0, "CONNECTION_STRING_NEEDED_HERE");
}
}
问题是我不知道如何将连接字符串注入这个类。我不能用这样的连接字符串参数创建一个新的构造函数:
public class MigrationDataStoreFactory : IDbContextFactory<DataStore>
{
public string _connectionString { get; set; }
public MigrationDataStoreFactory(string connectionString)
{
_connectionString = connectionString;
}
public DataStore Create()
{
return new DataStore(0, new DateTimeProvider(() => DateTime.Now), _connectionString);
}
}
如果这样做,我会在运行时收到迁移引发的以下异常:
[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
除此之外,Unity 无论如何都不会实例化此类;它似乎只是被 Code First Migrations 按照惯例以某种方式调用,所以即使我能做到这一点也无济于事......
如果我在该方法中对连接字符串进行硬编码,一切正常,但出于显而易见的原因,我不想这样做。
有人可以帮忙吗?
【问题讨论】:
-
也许我完全误解了你的问题,但你不能只创建一个从 appconfig 读取连接字符串的包装类(例如 IDbConnectionConfig/DbConnectionConfig)并使用 Unity/inject 注册它吗?
-
是的,我可以,但我会将它注入什么? ;) 连接字符串已经使用 Unity 注入 - 问题是我不知道如何将 anything 注入
MigrationDataStoreFactory。 -
“上下文...默认构造函数”异常来自哪里?是 Unity 引发了该异常还是 EF 迁移?您可以使用堆栈跟踪更新您的问题吗?
-
为什么你不尝试使用 IDbConnectionFactory 而不是到处都提供连接字符串!
-
嗨@Steven,这是引发错误的迁移。我现在已经更新了这个问题,希望能稍微澄清一下,但正如我在编辑中所说,我不确定即使我可以创建一个新的构造函数它是否会有所帮助。
标签: c# entity-framework asp.net-mvc-4 dependency-injection unity-container