DI для Repositories в ASP.MVC

shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

DI для Repositories в ASP.MVC

Post by shadow7256 »

Есть ASP.NET MVC controller. Допустим он иногда использует какую то repository для работой с базой данных. Репозиторий передается через конструктор. Допустим вот так:

Code: Select all

public class HomeController : BaseController
{
   private IRoleRepository RoleRepository { get; set; }

   public HomeController (IRoleRepository repository)
   {
          RoleRepository = repository;
   }

 .......
}
но внутри контроллера есть несколько public методов которым нафиг этот репозиторий не нужен, но из за того что стоит DI контейнер и там этот интерфейс зарегистрирован, то каждый раз при создании объекта этого контроллера создается также и репозиторий (и при этом открывает соединение с базой данных).

1. Можно как то использовать репозиторий только там где надо? Можно, напрямую создавая его только в тех методах где он нужен. Но тут будут кричать приверженцы unit test'ов типа если не передавать в конструкторе то как же юнит тесты писать, типа контроллер будет coupled с конкретным репозиторием. Есть ли какой то еще способ?

2. А как тогда закрывать соединение с базой, которой открыл этот репозиторий?

Каждый конкретный репозиторий унаследован от соотвествующего интерфейса и плюс от абстрактного класса BaseRepository, в котором находится собвственно контекст для работы с базой данных

Code: Select all

public abstract class BaseRepository : IDisposable
{
     private IContext context; // в конкретном случае здесь подставляется сессия NHibernate

    public void Dispose ()
    {
       context.Dispose();
    }
}

public class RoleRepository : BaseRepository, IRoleRepository
{

}
SergP
Уже с Приветом
Posts: 147
Joined: 13 Apr 2000 09:01

Re: DI для Repositories в ASP.MVC

Post by SergP »

А как context инициализируется в BaseRepository ? Можно отложить инициализацию context до первого обращения к context ?
shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

Re: DI для Repositories в ASP.MVC

Post by shadow7256 »

SergP wrote:А как context инициализируется в BaseRepository ? Можно отложить инициализацию context до первого обращения к context ?
Вы правы. Посмотрел код. Как только context инициализируется в BaseRepository тут же открывается сессия. Это неправильно. Я поменял код, чтобы перед каждой конкретной операцией проверялось открыта ли сессия, если нет, то только тогда открывать..

Но непонятно в какой момент освобождать сессию? Можно конечно грубо сделать внутри NHibernateDataContext класса в каждой операции открывать сессию и в конце закрывать. Тогда клиенту вообще ни о чем заботиться не надо, но будет ли это особо эффективно..
SergP
Уже с Приветом
Posts: 147
Joined: 13 Apr 2000 09:01

Re: DI для Repositories в ASP.MVC

Post by SergP »

shadow7256 wrote:Но непонятно в какой момент освобождать сессию?
Если в контроллере нет методов, выполнение которых занимает большое время, то Ваш контроллер можно подкоорректировать так:

Code: Select all

public class HomeController : BaseController
{
	private IRoleRepository RoleRepository { get; set; }

        protected override void Dispose(bool disposing)
        {
            this.RoleRepository.Dispose();
            base.Dispose(disposing);
        }
        .......
}
Я подразумеваю, что instance контроллера создается framework-ом по приходу HTTP request, и уничтожается (тем же framework-ом) при отправке HTTP response. Тогда время жизни этой instance довольно короткое ("если в контроллере нет методов, выполнение которых занимает большое время"), и можно держать сессию до Controller.Dispose().

Если же Вы сами создаете instance контроллера, то надо смотреть на ее время жизни - возможно, что эта идея с Dispose() будет плохой.
shadow7256
Уже с Приветом
Posts: 9392
Joined: 18 Mar 2004 15:11
Location: New York -> FL

Re: DI для Repositories в ASP.MVC

Post by shadow7256 »

Да, инстансы контроллеров создаются фреймворком. Тогда в каждом контроллере где есть репозитории придется перегружать Dispose. Ну что же. Такой подход тоже имеет место быть :) по крайней мере я сам котролирую где и что освобождать
User avatar
olegy
Уже с Приветом
Posts: 2127
Joined: 07 Nov 2000 10:01
Location: San Diego, CA, USA

Re: DI для Repositories в ASP.MVC

Post by olegy »

Вообще то DI pattern подразумевает наличие не только constructor based injector, но и property injector. Тогда ваш репозиторий будет как бы on demand
http://jeremybytes.blogspot.com/2014/01 ... ction.html" onclick="window.open(this.href);return false;
Я гражданин Украины, киевлянин и я против хунты!

Return to “Вопросы и новости IT”