Използване на филтри за събиране на NHibernate с DDD колекции

Опитвам се да картографирам модел на домейн в NHibernate. Моделът на домейна е реализиран с това, което според мен е DDD стил. Картографирането работи най-вече, но след това, когато се опитам да използвам филтър за колекция в колекция, получавам изключение, което казва: Колекцията не е реферирана.

Знам, че проблемът идва от това как съм внедрил колекцията. Моят въпрос: Възможно ли е да се използват филтри за колекции в nHibernate върху колекции, реализирани по този начин, или просто трябва да го забравя, т.е. nHibernate не може да работи с това.

Кодът е както следва:

Person
{
   IList<Address> _addresses = new List<Address>();
   public string FirstName {get; set;}
   ...
   public void addAddress(Address address)
   {
      // ... do some checks or validation
      _addresses.Add(address);
   }

   public void removeAddress(Address address) {...}

   public ReadOnlyCollection<Address> Addresses 
   { 
      get { return new ReadOnlyCollection<Address>(_addresses); }
   }
}

Основният проблем е, че не искам да излагам колекцията от вътрешни адреси публично. Всяко друго нещо работи, използвам достъпа field.camelcase-underscore, така че nHibernate взаимодейства директно с полето. Работих върху книгата Hibernate in Action, а сега съм в глава 7, където се занимава с филтри за събиране.

Има ли начин да се заобиколи това. Накарах го да работи, като изложих вътрешната колекция по следния начин:

public ReadOnlyCollection<Address> Addresses 
{ 
   get { return _addresses; }
}

но наистина не искам да правя това.

Помощта наистина ще бъде оценена.

Джид


person Jideo    schedule 12.10.2009    source източник


Отговори (1)


Ако си спомням правилно - филтърът NHibernate работи като допълнителна клауза в sql заявки за намаляване на върнатите редове от db.

Въпросът ми към Вас е - защо Ви трябва това?
Искам да кажа - колко адреса може да има един човек? 1? 5? 10?


Относно изолацията на колекцията...

Аз самият просто го приемам като жертва за NHibernate (точно като ctor без аргументи и "виртуалност") и използвам открит IList навсякъде (с частни сетери), само за да намаля техническата сложност. Съдържанието им със сигурност може да се променя отвън, но аз просто не го правя.

По-важно е да поддържате кода лесно разбираем, отколкото да го направите супер безопасен. Безопасността ще последва.

person Arnis Lapsa    schedule 12.03.2011
comment
Ако изложите IList, как се справяте с потребителя, който променя директно колекцията? Разбирам, че най-добрата практика е да създадете помощен метод, за да направите това, за да можете да управлявате двупосочната връзка. - person Mike Cole; 13.03.2011
comment
@Mike, не се справям с това. Това имах предвид с жертвата. Просто си измислям конвенция да не правя това. Може да не работи, ако нямате контрол върху потребителите (лесно за мен - дори нямам екип в проекта си, сам съм). Какво имахте предвид с помощни методи, обработващи двупосочни връзки? - person Arnis Lapsa; 13.03.2011
comment
@Mike как ще се справиш с бъркането с отражението и модифицирането на частната колекция? :) - person Arnis Lapsa; 13.03.2011
comment
LOL, добра гледна точка. Вероятно щях да пусна някакъв сигнал, за да мога да ударя някого с главата надолу, ако го направи. - person Mike Cole; 13.03.2011