2012-06-24 2 views
1

Я использую контейнер IOC Spring.NET в своем приложении ASP.NET MVC 4. Каждый контроллер получать DataContext EF из контейнера:Spring.NET IOC/MVC - контекст базы данных

private readonly IDBContext db = 
     (IDBContext) ApplicationHelper.ApplicationContext.GetObject("DatabaseContext"); 

Я scaffolded контроллеры, и по умолчанию они реализуют IDisposable интерфейс, в котором соединение DB расположена - как это:

protected override void Dispose(bool disposing) 
    { 
     this.db.Dispose(); 
     base.Dispose(disposing); 
    } 

Это нормально - я хотел бы сохранить его таким образом. Однако второй контроллер, который вызывается, дает исключение, указав, что контекст базы данных удален.

Итак - что бы я хотел сделать, это проверить контейнер контейнера IOC, если объект был удален, когда следующий контроллер вызывает метод GetObject(). Возможно ли это, или я должен изменить свой дизайн?

ответ

1

По умолчанию объект, настроенный в вашем контейнере веб-приложения spring.net, имеет "application" scope. Это означает, что ваш экземпляр с именем DatabaseContext создается один раз - при запуске веб-приложения. Первый контроллер, который использует этот экземпляр, использует его, и после этого он не может использоваться каким-либо другим контроллером.

Как правило, при использовании контейнера IOC плохой практикой управлять временем жизни объекта самостоятельно, как вы это делаете здесь, в контроллерах с реализацией реализации. Когда это возможно, вы должны позволить вашему контейнеру управлять сроками жизни объекта.

В этом конкретном случае может возникнуть смысл создать ваш DatabaseContext с использованием области request. При этом весенний контейнер будет располагать ваш DatabaseContext в конце вашего запроса. При этом вы можете удалить this.db.Dispose(); от Controller.Dispose.

Недавно появился вопрос IoC (spring.net) with asp.net - ctor injected non-singleton objects on controller - where do I dispose?; это может вас заинтересовать.

+0

Sweet - место сверху ответ. Благодаря! Я добавил scope = "request" и удалит все строительные леса, и это сработает! –

0

Похоже, что в вашем методе настройки контейнера IoC вы сконфигурировали IDBContext как одноэлементный.

Измените его на основе экземпляра IDBContext.

Смежные вопросы