Краткий ответ:
Вы используете спецификации в основном на своем уровне обслуживания, поэтому там.
Длинный ответ: Прежде всего, естьздесь два вопроса:
Где должны находиться ваши спецификации и где они должны быть новыми?
Как и ваши интерфейсы репозитория, ваши спецификации должны жить на уровне домена, как они есть.В конце концов, для конкретного домена.Есть вопрос по SO , в котором обсуждается это на интерфейсах репозитория.
Хотя, где они должны быть новыми?Ну, я использую LinqSpecs в своих репозиториях, и в большинстве случаев в моем репозитории есть три метода:
public interface ILinqSpecsRepository<T>
{
IEnumerable<T> FindAll(Specification<T> specification);
IEnumerable<T> FindAll<TRelated>(Specification<T> specification, Expression<Func<T, TRelated>> fetchExpression);
T FindOne(Specification<T> specification);
}
Остальные мои запросы построены на моем сервисном уровне.Это предотвращает раздувание репозиториев с помощью таких методов, как GetUserByEmail, GetUserById, GetUserByStatus и т. Д. В моем сервисе я обновляю свои спецификации и передаю их методам FindAll или FindOne моего репозитория.Например:
public User GetUserByEmail(string email)
{
var withEmail = new UserByEmail(email); // the specification
return userRepository.FindOne(withEmail);
}
и вот спецификация:
public class UserByEmail : Specification<User>
{
private readonly string email;
public UserByEmail(string email)
{
this.email = email;
}
#region Overrides of Specification<User>
public override Expression<Func<User, bool>> IsSatisfiedBy()
{
return x => x.Email == email;
}
#endregion
}
Итак, чтобы ответить на ваш вопрос, спецификации появились в слое обслуживания (в моей книге).
Мне кажется, что единственное, что должно быть введено в классы модели, это "сервисы"
IMO, вы не должны вводить что-либо в сущности домена.
Добавьте к этому, что для данной Спецификации требуется репозиторий, чтобы определить, «удовлетворен» он или нет.
Это запах кода .Я бы пересмотрел ваш код там.Спецификация определенно не должна требовать хранилища.