【问题标题】:DbContext with Ninject ADO.NETDbContext 与 Ninject ADO.NET
【发布时间】:2016-12-19 23:53:49
【问题描述】:

我正在做一个完成了 80% 的大项目(虽然有些功能需要实现)。但最近我们发现该项目不允许并发请求(我的意思是多个用户请求同一个存储库)。有时我们得到空参考和有时“执行无法打开可用连接,连接状态已关闭”等。 我们的源代码在世界之外受到严格限制。这是一些代码。如果有任何架构问题,请告诉我,因为架构人员离开了公司。它使用的是ninject 3.0。我已经将 InRequestScope() 用于所有经理的存储库,但没有运气

更新:我这里没有使用任何 ORM,我正在尝试通过我的 DbContext 类中的数据适配器连接 SqlServer

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);
}

当我在编辑器中编写所有内容时,我的代码中可能有一些错字

【问题讨论】:

  • 你能提供更多细节吗?您是否使用任何 ORM(例如 EF6)来访问数据库?哪个版本?或者您是否尝试使用本机驱动程序直接连接到数据库,哪个驱动程序? Sql Server、Oracle 等?
  • 空引用出现在哪一行?您的 Controller 仅调用 Save 方法。如果您也提供该方法的来源会有所帮助。

标签: c# .net ado.net ninject


【解决方案1】:

我认为你在 Ninject Dependency Resolver 中这样做太复杂了。

您不应该使用 new 关键字创建 DbContext。相反,您应该让 Ninject 在请求范围内在线程范围内解析 DbContext。

要注册 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 类,并在其中添加一些特定的逻辑来解析对象。

例子:

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); } }
}

我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    您需要在 MyManager 中删除此初始化,因为您通过 IoC 传递了已初始化的 DbContext。

     DbContext _dbContext=new    
                DbContext("someParameter","connectionstring");
    

    您还需要删除 MyManager 类的 GetDataTable 中的 finally 块,因为根据经验,如果对象是通过 IoC 初始化的,它也应该被 IoC 销毁。

    finally{_dbContext.Close()}
    

    【讨论】:

    • 好的。让我试试 。但是 Ninject 家伙告诉我,我在 NinjectDependencyResolver 类中所做的事情是错误的,并且不是由 Ninject 处理的 var context=new DbContext("someparameter","connectionSrin"); }
    【解决方案3】:

    如果您在字段级别初始化某些内容,那么为什么要从构造函数再次对其进行初始化?

    private readonly  IMyRepository _iMyRepository;    
    DbContext _dbContext=new DbContext("someParameter","connectionstring");
    
    public MyManager(IMyRepository iMyRepository, DbContext dbContext)                    
    {      
         _iMyRepository=iMyRepository;
         _dbContext=dbContext;
    }
    

    这也可能是一个错字。要么从构造函数中移除 _dbContext 初始化,要么将初始化任务委托给这个类的调用者。

    多次初始化也可能是问题所在。因为您正在 NinjectDependencyResolver() 和 MyManager 中进行 dbcontext 初始化。为此,您会遇到两个不同的异常。我猜这是一个平台设计问题

    【讨论】:

    • 我明白你所说的,但问题是我们项目的其他部分(另一个团队的子项目使用初始化的_dbContext,我知道它是一团糟)。我会做一个测试。
    • 多次初始化也可能是问题所在。因为您正在 NinjectDependencyResolver() 和 MyManager 中进行 dbcontext 初始化。为此,您会遇到两个不同的异常,我猜这是平台设计问题
    【解决方案4】:

    两个问题:

    // 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;
       }
    

    为该字段创建的 new 将在构造函数被调用时被覆盖。

    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);
    }
    

    您在这里创建一次上下文并将其传递给每个对象创建。因此,您仍在重用上下文对象,而不是为每个请求范围创建它。

    【讨论】:

    • 我了解如何解决第一个问题。为了解决第二个问题,我应该做类似 kernel.Bind().To().WithConstructorArgument("_dbContext",new DbContext("someparameter","connectionStrin"));
    猜你喜欢
    • 1970-01-01
    • 2011-07-17
    • 2017-07-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多