Ninject ADO.NET 的 DbContext
DbContext with Ninject ADO.NET
我正在做一个完成了 80% 的大项目(虽然有些功能需要实现)。但最近我们发现该项目不允许并发请求(我的意思是多个用户请求同一个存储库)。有时我们得到空引用,有时 "Executed can not open available connection , connection state is closed" 等。
我们的源代码在世界之外受到严格限制。这是一些 code.Let 我知道是否存在任何架构问题,因为架构师离开了公司。它使用 ninject 3.0。我已经将 InRequestScope() 用于所有管理器的存储库,但运气不好
更新: 我在这里没有使用任何 ORM,我试图通过我的 DbContext 中的数据适配器连接 SqlServer class
public class DbContext
{
//execute query , nonquery etc using adapter & datatable
//Example
var dt=new DataTable();
_adapter=new _dbfactory.CreateAdapter();
_adapter.Fill(dt);
return dt;
}
//MyController
public class MyController
{
private readonly IMyManager_iMyManager;
public MyController(IMyManager iMyManager){_iMyManager=iMyManager}
public ActionResult Save()
{
_iMyManager.Save()
}
}
// My Manager
public class MyManager:IMyManager
{
private readonly IMyRepository _iMyRepository;
DbContext _dbContext=new
DbContext("someParameter","connectionstring");
public MyManager
(
IMyRepository iMyRepository, DbContext dbContext
)
{
_iMyRepository=iMyRepository;
_dbContext=dbContext;
}
Public DataTable GetDataTable()
{
try
{
_dbContext.Open();
_iMyRepository.GetDataTable()
}
catch(Exception ex){}
finally{_dbContext.Close()}
}
}
// 这里是存储库
Public class MyRepository:IMyRepository
{
public _dbContext;
public MyRepository(DbContext dbContext)
{
_dbContext=dbContext;
}
public DataTable GetDataTable()
{ return _dbContext.ExecuteQuery()}
}
最后这是我们的 ninject 绑定
public class NinjectDependencyResolver()
{
var context=new DbContext("someparameter","connectionStrin");
kernel.Bind<IMyManager>().To<MyManager>().WithConstructorArgument("_dbContext",context);
kernel.Bind<IMyRepository >().To<MyRepository >().WithConstructorArgument("_dbContext",context);
}
我的代码中可能有一些拼写错误,因为我在 so 编辑器中编写了所有内容
如果您在字段级别初始化某些东西,那么为什么要从构造函数再次初始化它?
private readonly IMyRepository _iMyRepository;
DbContext _dbContext=new DbContext("someParameter","connectionstring");
public MyManager(IMyRepository iMyRepository, DbContext dbContext)
{
_iMyRepository=iMyRepository;
_dbContext=dbContext;
}
这也可能是一个错字。从构造函数中删除 _dbContext 初始化,或者将初始化任务委托给此 class.
的调用者
多次初始化也可能是问题所在。因为您正在 NinjectDependencyResolver() 和 MyManager 中进行 dbcontext 初始化。为此,您将获得两个不同的例外。我猜这是一个平台设计问题
您需要在 MyManager
中删除此初始化,因为您通过 IoC 传递了初始化的 DbContext。
DbContext _dbContext=new
DbContext("someParameter","connectionstring");
您还需要删除 MyManager class 中 GetDataTable 中的 finally
块,因为根据经验,如果对象是通过 IoC 初始化的,它应该被 IoC 销毁为嗯
finally{_dbContext.Close()}
我认为你在 Ninject 依赖解析器中做的太复杂了。
您不应使用新关键字创建 DbContext。相反,您应该使 Ninject 解析 DbContext in request scope 或 in thread scope.
要注册 DbContext,您可以这样做:
kernel.Bind<DbContext>().To<MyDbContext>().WithConstructorArgument("someArgument", "someValue").InRequestScope();
kernel.Bind<IMyManager>().To<MyManager>().InRequestScope();
kernel.Bind<IMyRepository>().To<MyRepository>().InRequestScope();
您不需要将构造函数参数精确到 DbContext,因为 DbContext 仅在 Ninject.
中注册过一次
您还可以将 DbContext 注册到 DbContextProvider class,然后您可以添加一些特定的逻辑来解析对象。
示例:
kernel.Bind<DbContext>().ToProvider<MyDbContextProvider>().InRequestScope();
internal class MyDbContextProvider : Ninject.Activation.IProvider
{
public object Create(IContext context)
{
return new MyDbContext("connectionStringArgument";
}
public Type Type { get { return typeof (MyDbContext); } }
}
希望对您有所帮助。
两个问题:
// My Manager
public class MyManager:IMyManager
{
private readonly IMyRepository _iMyRepository;
DbContext _dbContext=new
DbContext("someParameter","connectionstring");
public MyManager
(
IMyRepository iMyRepository, DbContext dbContext
)
{
_iMyRepository=iMyRepository;
_dbContext=dbContext;
}
调用构造函数时,为该字段创建的新内容将被覆盖。
public class NinjectDependencyResolver()
{
var context=new DbContext("someparameter","connectionStrin");
kernel.Bind<IMyManager>().To<MyManager>().WithConstructorArgument("_dbContext",context);
kernel.Bind<IMyRepository >().To<MyRepository >().WithConstructorArgument("_dbContext",context);
}
您在这里创建一次上下文并将其传递给每个对象创建。所以你仍然在重复使用上下文对象,而不是为每个请求范围创建它。
我正在做一个完成了 80% 的大项目(虽然有些功能需要实现)。但最近我们发现该项目不允许并发请求(我的意思是多个用户请求同一个存储库)。有时我们得到空引用,有时 "Executed can not open available connection , connection state is closed" 等。 我们的源代码在世界之外受到严格限制。这是一些 code.Let 我知道是否存在任何架构问题,因为架构师离开了公司。它使用 ninject 3.0。我已经将 InRequestScope() 用于所有管理器的存储库,但运气不好
更新: 我在这里没有使用任何 ORM,我试图通过我的 DbContext 中的数据适配器连接 SqlServer class
public class DbContext
{
//execute query , nonquery etc using adapter & datatable
//Example
var dt=new DataTable();
_adapter=new _dbfactory.CreateAdapter();
_adapter.Fill(dt);
return dt;
}
//MyController
public class MyController
{
private readonly IMyManager_iMyManager;
public MyController(IMyManager iMyManager){_iMyManager=iMyManager}
public ActionResult Save()
{
_iMyManager.Save()
}
}
// My Manager
public class MyManager:IMyManager
{
private readonly IMyRepository _iMyRepository;
DbContext _dbContext=new
DbContext("someParameter","connectionstring");
public MyManager
(
IMyRepository iMyRepository, DbContext dbContext
)
{
_iMyRepository=iMyRepository;
_dbContext=dbContext;
}
Public DataTable GetDataTable()
{
try
{
_dbContext.Open();
_iMyRepository.GetDataTable()
}
catch(Exception ex){}
finally{_dbContext.Close()}
}
}
// 这里是存储库
Public class MyRepository:IMyRepository
{
public _dbContext;
public MyRepository(DbContext dbContext)
{
_dbContext=dbContext;
}
public DataTable GetDataTable()
{ return _dbContext.ExecuteQuery()}
}
最后这是我们的 ninject 绑定
public class NinjectDependencyResolver()
{
var context=new DbContext("someparameter","connectionStrin");
kernel.Bind<IMyManager>().To<MyManager>().WithConstructorArgument("_dbContext",context);
kernel.Bind<IMyRepository >().To<MyRepository >().WithConstructorArgument("_dbContext",context);
}
我的代码中可能有一些拼写错误,因为我在 so 编辑器中编写了所有内容
如果您在字段级别初始化某些东西,那么为什么要从构造函数再次初始化它?
private readonly IMyRepository _iMyRepository;
DbContext _dbContext=new DbContext("someParameter","connectionstring");
public MyManager(IMyRepository iMyRepository, DbContext dbContext)
{
_iMyRepository=iMyRepository;
_dbContext=dbContext;
}
这也可能是一个错字。从构造函数中删除 _dbContext 初始化,或者将初始化任务委托给此 class.
的调用者多次初始化也可能是问题所在。因为您正在 NinjectDependencyResolver() 和 MyManager 中进行 dbcontext 初始化。为此,您将获得两个不同的例外。我猜这是一个平台设计问题
您需要在 MyManager
中删除此初始化,因为您通过 IoC 传递了初始化的 DbContext。
DbContext _dbContext=new
DbContext("someParameter","connectionstring");
您还需要删除 MyManager class 中 GetDataTable 中的 finally
块,因为根据经验,如果对象是通过 IoC 初始化的,它应该被 IoC 销毁为嗯
finally{_dbContext.Close()}
我认为你在 Ninject 依赖解析器中做的太复杂了。
您不应使用新关键字创建 DbContext。相反,您应该使 Ninject 解析 DbContext in request scope 或 in thread scope.
要注册 DbContext,您可以这样做:
kernel.Bind<DbContext>().To<MyDbContext>().WithConstructorArgument("someArgument", "someValue").InRequestScope();
kernel.Bind<IMyManager>().To<MyManager>().InRequestScope();
kernel.Bind<IMyRepository>().To<MyRepository>().InRequestScope();
您不需要将构造函数参数精确到 DbContext,因为 DbContext 仅在 Ninject.
中注册过一次您还可以将 DbContext 注册到 DbContextProvider class,然后您可以添加一些特定的逻辑来解析对象。
示例:
kernel.Bind<DbContext>().ToProvider<MyDbContextProvider>().InRequestScope();
internal class MyDbContextProvider : Ninject.Activation.IProvider
{
public object Create(IContext context)
{
return new MyDbContext("connectionStringArgument";
}
public Type Type { get { return typeof (MyDbContext); } }
}
希望对您有所帮助。
两个问题:
// My Manager
public class MyManager:IMyManager
{
private readonly IMyRepository _iMyRepository;
DbContext _dbContext=new
DbContext("someParameter","connectionstring");
public MyManager
(
IMyRepository iMyRepository, DbContext dbContext
)
{
_iMyRepository=iMyRepository;
_dbContext=dbContext;
}
调用构造函数时,为该字段创建的新内容将被覆盖。
public class NinjectDependencyResolver()
{
var context=new DbContext("someparameter","connectionStrin");
kernel.Bind<IMyManager>().To<MyManager>().WithConstructorArgument("_dbContext",context);
kernel.Bind<IMyRepository >().To<MyRepository >().WithConstructorArgument("_dbContext",context);
}
您在这里创建一次上下文并将其传递给每个对象创建。所以你仍然在重复使用上下文对象,而不是为每个请求范围创建它。