DbContext с Ninject ADO.NET

1

Я работаю над большим проектом, который завершил 80% (некоторые функции должны быть реализованы, хотя). Но недавно мы обнаружили, что проект не разрешает одновременные запросы (я имею в виду, что несколько пользователей запрашивают один и тот же репозиторий). Иногда мы получаем null referece, и иногда "Executed не может открыть доступное соединение, состояние соединения закрыто" и т.д. Наш исходный код сильно ограничен за пределами мира. Вот какой-то код. Сообщите мне, есть ли какая-либо архитектурная проблема, поскольку архитектурные ребята покинули компанию. Он использует ninject 3.0. Я уже использовал InRequestScope() для всех репозиториев менеджеров, но не повезло

Обновление: я не использую 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);
}

в моем коде может быть некоторая опечатка, поскольку я написал все в таком редакторе

Теги:
ado.net
ninject

4 ответа

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

Две проблемы:

// 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 <IMyManager> (). To <MyManager> (). WithConstructorArgument ("_ dbContext", new DbContext ("someparameter", "connectionStrin"));
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

Если вы инициализируете что-то на полевом уровне, то зачем вам инициализировать его снова из конструктора?

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
    Я понимаю, что вы сказали, но проблема в других частях нашего проекта (подпроекты другой команды используют инициализированный _dbContext, я знаю, что это беспорядок). Я сделаю тест.
  • 0
    множественная инициализация также может быть проблемой. поскольку вы выполняете инициализацию dbcontext как в NinjectDependencyResolver (), так и в MyManager. Для этого вы получаете два разных исключения, это проблема дизайна платформы, я думаю,

Ещё вопросы

Сообщество Overcoder
Наверх
Меню