使用Ninject ADO.NET的DbContext

时间:2016-12-14 15:56:05

标签: c# .net ado.net ninject

我正在开发一个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);
}

我的代码中可能会有一些拼写错误,因为我在编辑器中编写了所有内容

4 个答案:

答案 0 :(得分:3)

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

您不应该使用新关键字创建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); } }
}

我希望这会有所帮助。

答案 1 :(得分:0)

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

private readonly  IMyRepository _iMyRepository;    
DbContext _dbContext=new DbContext("someParameter","connectionstring");

public MyManager(IMyRepository iMyRepository, DbContext dbContext)                    
{      
     _iMyRepository=iMyRepository;
     _dbContext=dbContext;
}

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

多次初始化也可能是问题所在。因为您在NinjectDependencyResolver()和MyManager中进行dbcontext初始化。为此你得到两个不同的例外。这是我猜的平台设计问题

答案 2 :(得分:0)

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

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

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

finally{_dbContext.Close()}

答案 3 :(得分:0)

两个问题:

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

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