2016-12-14 73 views
1

我正在研究一个80%完成的大项目(虽然有些功能需要实现)。但是最近我们发现该项目不允许并发请求(我的意思是多个用户请求同一个存储库)。有时我们会得到空引用&有时“执行无法打开可用连接,连接状态已关闭”等。 我们的源代码严格限制在世界之外。这里有一些代码。让我知道是否有任何建筑问题,因为建筑家伙离开了公司。它使用ninject 3.0。我已经使用InRequestScope()的所有经理的库,但没有运气DbContext with Ninject ADO.NET

更新:我没有使用任何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); 
} 

有可能有一些错字在我的代码,我写了一切,所以编辑

+0

你能提供更多的细节吗?您是否使用任何ORM(例如EF6)来访问数据库?哪个版本?或者你是否试图使用本地驱动程序直接连接到数据库,哪一个? Sql Server,Oracle等? – Vinod

+0

在这一行中,空引用出现?你的Controller只调用Save方法。如果您也提供该方法的来源,这将有所帮助。 –

回答

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

我希望这有助于。

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初始化。为此,你会得到两个不同的例外。这是一个平台设计问题,我猜

+0

我明白你说了什么,但问题是我们项目的其他部分(另一个团队的子项目使用初始化的_dbContext,我知道这是一团糟)。我会做一个测试。 –

+0

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

0

你需要删除MyManager这个初始化,因为你通过IoC传递初始化的DbContext。

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

您还需要去掉finally块在GetDataTable在MyManager类,因为作为一个经验法则,如果对象是通过IoC的初始化时,它应该由国际奥委会也被销毁。

finally{_dbContext.Close()} 
+0

好吧。让我尝试 。但Ninject的人告诉我,我在NinjectDependencyResolver类中做了什么是错误的,并没有处理Ninject var context = new DbContext(“someparameter”,“connectionStrin”); } –

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

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

+0

我明白如何解决第一个问题。为了解决第二个,我应该这样做kernel.Bind ()。为了().WithConstructorArgument( “_的DbContext”,新的DbContext( “someparameter”, “connectionStrin”)); –