2016-12-14 12 views
1

Я работаю над большим проектом, который заполнен на 80% (некоторые функции должны быть реализованы, хотя). Но недавно мы обнаружили, что проект не разрешает одновременные запросы (я имею в виду, что несколько пользователей запрашивают то же хранилище). Когда-то мы получаем null referece & иногда «Выполненные не могут открыть доступное соединение, состояние соединения закрыто» и т. Д. Наш исходный код сильно ограничен за пределами мира. Вот какой-то код. Сообщите мне, есть ли какая-либо архитектурная проблема, поскольку архитектурные ребята покинули компанию. Он использует ninject 3.0. Я уже использовал InRequestScope() для хранилищ все менеджера, но не повезлоDbContext с Ninject ADO.NET

Обновление: Я не использую любой ORM здесь, я пытаюсь подключить SqlServer через адаптер данных в моем классе DbContext

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 из конструктора или делегируйте задачу инициализации вызывающему классу этого класса.

Возможна также множественная инициализация. поскольку вы выполняете инициализацию dbcontext как в NinjectDependencyResolver(), так и в MyManager. Для этого вы получаете два разных исключения. Это проблема проектирования платформы, я думаю,

+0

Я понимаю, что сказал u, но проблема в других частях нашего проекта (подпроекты другой команды используют этот инициализированный _dbContext, я знаю, что это беспорядок). Я сделаю тест. –

+0

Многократная инициализация также может быть проблемой. поскольку вы выполняете инициализацию dbcontext как в NinjectDependencyResolver(), так и в MyManager. Для этого вы получаете два разных исключения, это проблема с дизайном платформы, я думаю, –

0

Вам необходимо удалить эту инициализацию в MyManager, поскольку вы передаете инициализированный DbContext через IoC.

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

Кроме того, необходимо удалить finally блок в GetDataTable в классе MyManager, поскольку, как правило, если объект инициализируется через IoC, он должен быть уничтожен 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 (). To () .WithConstructorArgument («_dbContext», новый DbContext («someparameter», «connectionStrin»)); –