1.Хочу задать вопрос по паттерну specification. Кто использовал его
реализацию для многокритериального поиска? Т.е. мне необходимо понять
насколько целесообразно его использование в небольшом проекте, ведь
можно обойтись обычными конструкциями запросов к репозиторию.
2. Где должно происходить создание экземпляров ISpecification и
передача их в репозиторий? В сервисе? Что если существуют такие
экземпляры классов (по кол-ву критериев)
public class ProductByNameSpecification : Specification<Product>
{
public ProductByNameSpecification(string nameToMatch)
: base(p => p.Name == nameToMatch)
{
}
}
В каком слое они должны быть расположены?
3. Не могли бы вы привести ваши тесты использования этого паттерна в
проекте, если они есть.
Спасибо!
On 27 окт, 10:10, "Alexander I. Zaytsev" <hazzik+nos...@gmail.com>
wrote:
> Отличная опечатка в теме;)
>
> 27 октября 2010 г. 12:08 пользователь menozz <menozgra...@gmail.com>написал:
ок, пусть будет репозиторий.
http://pastebin.com/cpCEnib6
Суть в том, что сюда будут приходить параметры с формы на основании
критериев поиска. Создавать экземпляры спецификации нужно здесь, если
вообще нужно? В моем понимании идея использования ISpecification
заключается в том, чтобы превратить этот репозиторий (я его называю
сервисом) в нечто без linq-выражений, чтобы читая методы было понятно
что делается. Там есть метод закоменченный с вариантом создания
ISpecification. Надеюсь, вопрос понятен. Все же хотелось бы посмотреть
на примеры, где действительно необходимо использование шаблона
спецификации (в рамках проекта побольше, хотя бы тестики
использования)
Спасибо.
On 27 окт, 12:52, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> По сути, используя LINQ, ты уже применяешь шаблон Specification.
>
> Объект Expression может добавлять в себя условия. Самое простое:
>
> var r = new int{1,2,3};
> IQueryable<int> query = r.Where(x => x > 1);
> query = query.OrderBy(x=> x);
> query = query.Count();
> ...
>
> Запросы на LINQ находятся в репозитории, сервису их не надо формировать.
> Нужно у репозитория сразу попросить то, что нужно.
>
> Если остались еще вопросы, то пиши.
>
> 27 октября 2010 г. 12:29 пользователь menozz <menozgra...@gmail.com>написал:
>
>
>
> > навеяно ранним утром ))
>
> > On 27 окт, 10:10, "Alexander I. Zaytsev" <hazzik+nos...@gmail.com<hazzik%2Bnos...@gmail.com>
On 27 окт, 16:36, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> Твой TaskService - это чистый репозиторий. А если разбить каждый его метод
> на отдельный класс запроса, то получится Query из CQRS.
>
> Я не увидел, где тебе надо хитро собирать объект запроса (ISpecification)
> для выборки данных. Все вполне прозрачно написано на Linq.
>
> Опиши, пожалуйста, корни проблемы, из-за которой ты начал смотреть в сторону
> рефакторинга и использовать шаблона Specification
>
> 27 октября 2010 г. 16:06 пользователь menozz <menozgra...@gmail.com>написал:
> > <hazzik%2Bnos...@gmail.com <hazzik%252Bnos...@gmail.com>>
Сейчас, например в реализации репозитория типа T:
public T FindBy(ISpecification<T> criteria)
{
return criteria.SatisfyingEntityFrom(All());
}
public IQueryable<T> FilterBy(ISpecification<T> criteria)
{
return criteria.SatisfyingEntitiesFrom(All());
}
Т.е. ISpecification не зависит от типа entity и все linq выражения
будут содержаться в соответствующих мини-классах. А имя будет
соответствовать его назначению.
В любом случае, огромное спасибо за потраченное время на составление
кода
Конструкция
в классе репозитория снимает эту проблему. Я могу вынести все
On 27 окт, 17:00, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> Я бы сделал такhttp://pastebin.com/arFGXV5B
>
> Часть кода пропущена, но думаю суть должна быть понятна.
>
> 27 октября 2010 г. 18:41 пользователь menozz <menozgra...@gmail.com>написал:
> > > > <hazzik%2Bnos...@gmail.com <hazzik%252Bnos...@gmail.com> <
> > hazzik%252Bnos...@gmail.com <hazzik%25252Bnos...@gmail.com>>>
http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43695
и вот так ее использует сервис:
http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43972
вобщем-то вполне читабельно )
Спасибо!
public virtual IList<Account> Managers { get; protected set; }
ну, вот так получилась спецификация:
Я не понял зачем используются операторы & и |, а не && и ||
Operators Overloadability
+, -, *, /, %, &, |, <<, >> All C# binary operators can be overloaded.
+, -, !, ~, ++, -, true, false All C# unary operators can be
overloaded.
==, !=, <, >, <= , >= All relational operators can be overloaded,
but only as pairs.
&&, || They can't be overloaded
Я бы рад, но они перегружены в Generic specification
>
> И еще вместо проверок на null можешь использовать шаблон Null Object, т.е.
> сделать NullSpecification, которая ничего не делает.
>
> 12 ноября 2010 г. 14:33 пользователь menozz <menozgra...@gmail.com> написал:
> > > > > hazzik%252Bnos...@gmail.com <hazzik%25252Bnos...@gmail.com> <
> > hazzik%25252Bnos...@gmail.com <hazzik%2525252Bnos...@gmail.com>>>>
> ...
>
> продолжение >>
Про Null, Ты прав, но пока руки не дошли до создания NullAccount и для
остальных.. [посыпая голову пеплом..]
On 12 ноя, 17:11, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> Еще глянул пару классов в домене.
>
> Например, класс Accounthttp://webtasks.codeplex.com/SourceControl/changeset/view/2226#43525.
> Ты сделал доменные функции добавления и удаления менеджера, который должны
> инкапсулировать список Managers, при этом сам список сделан публичным:
>
> public virtual IList<Account> Managers { get; protected set; }
>
> 12 ноября 2010 г. 14:33 пользователь menozz <menozgra...@gmail.com> написал:
> > > > > hazzik%252Bnos...@gmail.com <hazzik%25252Bnos...@gmail.com> <
> > hazzik%25252Bnos...@gmail.com <hazzik%2525252Bnos...@gmail.com>>>>
> ...
>
> продолжение >>
On 12 ноя, 17:34, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> Интересная идея, но не очевидная для того, кто читает код.
>
> 12 ноября 2010 г. 19:29 пользователь menozz <menozgra...@gmail.com> написал:
> > > > hazzik%25252Bnos...@gmail.com <hazzik%2525252Bnos...@gmail.com> <
> > hazzik%2525252Bnos...@gmail.com <hazzik%252525252Bnos...@gmail.com>>>>>
>
> > > > > > > > > > > wrote:
> > > > > > > > > > > > Отличная опечатка в теме;)
>
> > > > > > > > > > > > 27 октября 2010 г. 12:08 пользователь menozz <
> > > > > > > menozgra...@gmail.com
> > > > > > > > > > > >написал:
>
> > > > > > > > > > > > > Доброе утро, коллеги!
>
> > > > > > > > > > > > > 1.Хочу задать вопрос по паттерну specification. Кто
> > > > > > > использовал
> > > > > > > > > его
> > > > > > > > > > > > > реализацию для многокритериального поиска? Т.е. мне
> > > > необходимо
> > > > > > > > > понять
>
> ...
>
> продолжение >>
в том смысле, что issatisfied говорит о том, что удовлетворяет ли
объект условию. Если нет, то в группе условных операторов он
пропускается.
On 12 ноя, 17:38, "Alexander I. Zaytsev" <hazzik+nos...@gmail.com>
wrote:
> Нашел закоментированный NullSpecificationhttp://webtasks.codeplex.com/SourceControl/changeset/view/2226#43517
>
> <http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43517>Там
> принципиальная ошибка: Expressioin должен возвращать x=>true;
>
> 12 ноября 2010 г. 19:35 пользователь menozz <menozgra...@gmail.com> написал:
> > > > hazzik%25252Bnos...@gmail.com
>
> ...
>
> продолжение >>
On 12 ноя, 17:43, "Alexander I. Zaytsev" <hazzik+nos...@gmail.com>
wrote:
> Хотя нет. Я не прав. В зависимости от контекста: при использовании внутри Or
> должен возвращать false, внутри And true
>
> лучше переопределить | и & в NullSpecification (лучше через виртуальную
> перегрузку методов а не операндов)
>
> 12 ноября 2010 г. 19:38 пользователь Alexander I. Zaytsev <
> hazzik+nos...@gmail.com <hazzik%2Bnos...@gmail.com>> написал:
>
> > Нашел закоментированный NullSpecification
> >http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43517
>
> > <http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43517>Там
> > принципиальная ошибка: Expressioin должен возвращать x=>true;
>
> > 12 ноября 2010 г. 19:35 пользователь menozz <menozgra...@gmail.com>написал:
> ...
>
> продолжение >>
> ...
>
> продолжение >>
А.., понял твою мысль.. ну, да я его использовал только в одном
случае, а потом вообще удалил, поэтому закоменчен. спасибо, буду иметь
в виду.
> >http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43517
>
> > <http://webtasks.codeplex.com/SourceControl/changeset/view/2226#43517>Там
> > принципиальная ошибка: Expressioin должен возвращать x=>true;
>
> > 12 ноября 2010 г. 19:35 пользователь menozz <menozgra...@gmail.com>написал:
> ...
>
> продолжение >>
Account participant = accountRepository.GetAccount(id);
if (participant != null)
{
IList<UniversalModelDDL> models =
View.Participants;
var universalModel = new
UniversalModelDDL(participant.UID, participant.FullName);
if (!models.Contains(universalModel))
{
models.Add(universalModel);
View.Participants = models;
}
}
репозиторий должен вернуть экземпляр NullAccount, если по id не
найден объект?
> ...
>
> продолжение >>
инкапсулируем:
protected IList<Participant> participants;
паблик свойство:
public virtual IEnumerable<Account> Participants
{
get { return participants.Select(x => x.Login); }
}
class ContainsInParticipantFullName : Specification<Task>
{
readonly string _nameToMatch;
public ContainsInParticipantFullName(string nameToMatch)
{
_nameToMatch = nameToMatch;
}
public override System.Linq.Expressions.Expression<Func<Task,
bool>> IsSatisfiedBy()
{
//return x => x.ParticipantEntityList.Any(p =>
p.Login.FullName.Contains(_nameToMatch)); раньше так
return x => x.Participants.Any(p =>
p.Login.FullName.Contains(_nameToMatch)); //здесь проблема.
^^^^^^^^^^^^^
}
}
как составить запрос к IEnumerable паблик свойству, чтобы бд смогла
интерпретировать нормально?
On 12 ноя, 20:49, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> Вот здесь есть более подробноhttp://blog.byndyu.ru/2010/05/domain-driven-design.html
>
> <http://blog.byndyu.ru/2010/05/domain-driven-design.html>Вкратце, у
> интерфейса IList есть метод Add(), который открывает добавление менеджеров
> без доменной логики, которая содержится в AddManager и RemoveManager.
>
> 12 ноября 2010 г. 19:35 пользователь menozz <menozgra...@gmail.com> написал:
> > > > hazzik%25252Bnos...@gmail.com <hazzik%2525252Bnos...@gmail.com> <
> > hazzik%2525252Bnos...@gmail.com <hazzik%252525252Bnos...@gmail.com>>>>>
public virtual IEnumerable<Task>
GetTasksByDepartmentForOtherRole(Account account,
Department department)
{
return _repository.FilterBy(x => x.Status ==
TaskStatus.InProgress)
.Where(x => x.Department.WebPath ==
department.WebPath)
.Where(x => x.Owner == account || x.Participants.Any(p =>
p == account));
^^^^^^^^^^^^^^^^^ не замапленное свойство. нормально работает только с
замапленным свойством
}
Как это побороть, подскажите пожалуйста?
> ...
>
> продолжение >>
HasMany<Participant>(Reveal.Property<Task>("_participants"))
.KeyColumns.Add("IDtask")
.Inverse()
.Cascade.AllDeleteOrphan().LazyLoad()
.AsBag();
Таким образом получаем:
protected virtual IList<Participant> _participants { get; set;}
и
public virtual IEnumerable<Account> Participants
{
get
{
return _participants.Select(x => x.Login);
}
protected set{}
}
и переписанный класс спецификации под использование Participants.
Насколько безграмотно существование protected set в последней
проперти[сеттер нужен для маппинга, само свойство для составления linq
condition]? Может есть более элегантное решение?
On 12 ноя, 20:49, Alexander Byndyu <alexander.byn...@gmail.com> wrote:
> Вот здесь есть более подробноhttp://blog.byndyu.ru/2010/05/domain-driven-design.html
>
> <http://blog.byndyu.ru/2010/05/domain-driven-design.html>Вкратце, у
> интерфейса IList есть метод Add(), который открывает добавление менеджеров
> без доменной логики, которая содержится в AddManager и RemoveManager.
>
> 12 ноября 2010 г. 19:35 пользователь menozz <menozgra...@gmail.com> написал:
> > > > > > > hazzik%252Bnos...@gmail.com <hazzik%25252Bnos...@gmail.com> <
>
> ...
>
> продолжение >>
On 15 ноя, 09:19, "Alexander I. Zaytsev" <hazzik+nos...@gmail.com>
wrote:
> Саня, .Access.ReadOnlyPropertyThroughCamelCaseField() ему все поломает:)
>
> В данном случае protected set это нормально, но лучше его сделать приватным
> (NH по-фигу на модификатор доступа)
>
> 15 ноября 2010 г. 9:07 пользователь Alexander Byndyu <
> alexander.byn...@gmail.com> написал:
>
> > Можно добавить в маппинг:
> > .Access.ReadOnlyPropertyThroughCamelCaseField()
>
> > 15 ноября 2010 г. 2:10 пользователь menozz <menozgra...@gmail.com>написал:
> ...
>
> продолжение >>