Как далеко заходит введение зависимости? - PullRequest
5 голосов
/ 14 марта 2010

Решение для моего веб-приложения состоит из 3 проектов:

  1. Веб-приложение (ASP.NET MVC)
  2. Уровень бизнес-логики (библиотека классов)
  3. Уровень базы данных(Entity Framework)

Я хочу использовать Ninject для управления временем жизни DataContext, сгенерированным Entity Framework в Database Layer.

Уровень бизнес-логики состоит из классов, которые ссылаются на репозитории (расположены на уровне базы данных), а мое приложение ASP.NET MVC ссылается на классы обслуживания уровня бизнес-логики для выполнения кода.Каждый репозиторий создает экземпляр объекта MyDataContext из Entity Framework

Репозиторий

public class MyRepository
{
     private MyDataContext db;
     public MyRepository
     {
        this.db = new MyDataContext();
     }

     // methods
}

Классы бизнес-логики

public class BizLogicClass
{
     private MyRepository repos;
     public MyRepository
     {
          this.repos = new MyRepository();
     }

     // do stuff with the repos
}

Будет Ninject обрабатывать время жизни MyDataContext несмотря на длинную цепочку зависимостей от веб-приложения до уровня данных?

Ответы [ 2 ]

3 голосов
/ 14 марта 2010

Просто хочу отметить, что Autofac с интеграцией ASP.Net имеет встроенную поддержку времени жизни запроса.Разрешите экземпляры в RequestContainer, и они будут удалены (если реализовано IDisposable) в конце запроса.

Вы должны сделать свои уроки DI дружественными, хотя:

public class MyRepository
{
     private MyDataContext db;
     public MyRepository(MyDataContext context)
     {
        this.db = context;
     }

     // methods
}

public class BizLogicClass
{
     private MyRepository repos;
     public BizLogicClass(MyRepository repository)
     {
          this.repos = repository;
     }

     // do stuff with the repos
}
3 голосов
/ 14 марта 2010

EDIT

У меня есть некоторые проблемы с этим некоторое время назад, но теперь, похоже, работает:

Bind<CamelTrapEntities>().To<CamelTrapEntities>().Using<OnePerRequestBehavior>();

Вместо использования HttpModule можно использовать OnePerRequestBehavior, и он позаботится об обработке контекста в текущем запросе.

РЕДАКТИРОВАТЬ 2

OnePerRequestBehavior необходимо зарегистрировать в web.config, поскольку он также зависит от HttpModule:

В IIS6:

<system.web>
  <httpModules>
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  </httpModules>
</system.web> 

С IIS7:

<system.webServer> 
  <modules>
    <add name="OnePerRequestModule" type="Ninject.Core.Behavior.OnePerRequestModule, Ninject.Core"/>
  </modules>
</system.webServer>

ПРЕДЫДУЩИЙ ОТВЕТ

Вы несете ответственность за удаление контекста, когда он не нужен. Самый популярный способ в ASP.NET - иметь один ObjectContext на запрос. Я делаю это, имея HttpModule:

public class CamelTrapEntitiesHttpModule : IHttpModule
{
    public void Init(HttpApplication application)
    {
        application.BeginRequest += ApplicationBeginRequest;
        application.EndRequest += ApplicationEndRequest;
    }

    private void ApplicationEndRequest(object sender, EventArgs e)
    {
        ((CamelTrapEntities) HttpContext.Current.Items[@"CamelTrapEntities"]).Dispose();
    }

    private static void ApplicationBeginRequest(Object source, EventArgs e)
    {
        HttpContext.Current.Items[@"CamelTrapEntities"] = new CamelTrapEntities();            
    }
}

Это правило инъекции:

Bind<CamelTrapEntities>().ToMethod(c => (CamelTrapEntities) HttpContext.Current.Items[@"CamelTrapEntities"]);

Мой репозиторий принимает ObjectContext в конструкторе:

public Repository(CamelTrapEntities ctx)
{
    _ctx = ctx;
}
...