Mehdime.Entity
来管理控制台应用程序中的DBContext派生类。我也在使用NInject。
我的DBContext派生类的连接字符串部分是从标准app.config ConnectionStrings生成的,也是通过命令行参数(在我的控制台应用程序中)进入的AppDomain值生成的。
我的DBContext派生类使用程序实现的类来编写连接字符串,该类考虑了命令行参数,如下所示:
public class TaskManagementDbContext : DbContext
{
public TaskManagementDbContext(IConnectionStringResolver csr) :
base(csr.GetConnectionString("Default"))
{
}
}
(IConnectionStringResolver
基本上实现GetConnectionString()
,它通过使用给定的命名标准app.config ConnectionString和命令行参数来返回连接字符串。
当我使用NInject直接实例化DbContext但在尝试与Mehdime.Entity
一起使用时,这是正常的,它正在进行实例化AmbientDbContextLocator
并抛出MissingMethodException
,因为它要求我的DBContext派生类具有无参数构造函数:
public class TaskRepository : ITaskRepository
{
private readonly IAmbientDbContextLocator _ambientDbContextLocator;
private TaskManagementDbContext DbContext
{
get
{
// MissingMethodException thrown "No parameterless constructor defined for this object"
var dbContext = _ambientDbContextLocator.Get<TaskManagementDbContext>();
...
}
}
在这种情况下,如何在运行时向我的DBContext派生类提供连接字符串?我怀疑我的方式是错误的。感谢。
答案 0 :(得分:2)
行。我已经找到了解决方案,我将这个问题放在这里给其他人:
IDbContextFactory
实现(见下文)。我将它放在与我的数据访问层(即我的DbContexts)相同的类库中。你将在我的例子中看到我如何“寻找”一个特定的构造函数原型(在我的例子中,类型为IDbContextFactory
的1个参数 - 你的无疑会有所不同)。如果找到,请获取实际参数并调用DBContext派生类的新实例。如果没有找到,你可以抛出异常,或者在我的情况下,尝试调用默认构造函数(如果存在)。代码:
using System;
using System.Data.Entity;
using Mehdime.Entity;
using Ninject;
using TaskProcessor.Common;
namespace TaskProcessor.Data.Connection
{
public class DbContextWithCSRFactory : IDbContextFactory
{
public TDbContext CreateDbContext<TDbContext>() where TDbContext : DbContext
{
// Try to locate a constuctor with a single IConnectionStringResolver parameter...
var ci = typeof(TDbContext).GetConstructor(new[] { typeof(IConnectionStringResolver) });
if(ci != null)
{
// Call it with the actual parameter
var param1 = GlobalKernel.Instance.Get<IConnectionStringResolver>();
return (TDbContext)ci.Invoke(new object[] { param1 });
}
// Call parameterless constuctor instead (this is the default of what DbContextScope does)
return (TDbContext)Activator.CreateInstance<TDbContext>();
}
}
}
IDbContextFactory
实现:代码:
private void AddBindings(IKernel kernel)
{ ...
kernel.Bind<IDbContextFactory>().To<Data.Connection.DbContextWithCSRFactory>().InSingletonScope();
}
现在一切都已到位。