Как создать правило проверки с помощью NRules?
Я только что открыл NRules для.NET. Я хотел бы создать правило, которое предотвращает создание объекта, если значение поля / свойства недопустимо. Например, учитывая следующий класс:
public class Customer
{
public string Name { get; private set; }
public bool IsPreferred { get; set; }
public Customer(string name)
{
Name = name;
}
}
Я хотел бы создать правило, которое будет генерировать исключение, когда "Имя" является пустым или пустым, таким образом, отменять создание объекта, а также генерировать пользовательское сообщение: необходимо указать имя клиента.
Можно ли это сделать с помощью NRules, если да, то как это сделать?
1 ответ
С NRules вы пишете правила с точки зрения конкретного домена или объектной модели. Поэтому вам нужен какой-то объект для хранения данных, чтобы вы могли затем вставить эти объекты в сеанс правил, а также сопоставить эти объекты с правилами. Я полагаю, что для сценария проверки вы бы использовали один из следующих:
- DTO из сервисного уровня
- ViewModel объект из уровня представления
- Объект Builder перед вызовом его метода Build (т.е. CustomerBuilder)
- Сам доменный объект (его создание, затем проверка и отбрасывание, если оно недействительно)
На более высоком уровне, сладкое место для NRules - это выражение изменчивой бизнес-логики в терминах модели стабильного домена. В этом случае вы можете разделить логику валидации на две группы: 1) валидация, которая является стабильной и определяет внутренний инвариант для объектов домена, то есть имя клиента не является пустым; и 2) изменчивая логика проверки (т. е. клиент предпочтителен при соблюдении определенных условий). Затем вы должны закодировать логику проверки типа 1 как утверждения в самой модели предметной области, а логику проверки типа 2 - как правила в терминах этих объектов предметной области.
В любом случае, на механическом уровне вы, вероятно, захотите, чтобы правила проверки вставляли ValidationError для каждой неудачной проверки, а затем в конце сеанса запроса для этих ошибок проверки и предотвращали создание объекта, если таковые имеются.
ObjectUnderValidation match = null;
When()
.Match<ObjectUnderValidation>(() => match, x => x.ValidationCondition);
Then()
.Do(ctx => ctx.Insert(new ValidationError(match, "Message")));
Позже при выполнении проверки:
var session = factory.CreateSession();
session.Insert(myObjectUnderValidation);
session.Fire();
var errors = session.Query<ValidationError>().ToList();
if (errors.Any())
//Don't construct
else
//Construct
Вы также можете абстрагировать некоторые из этих кодов, чтобы упростить их использование в вашем конкретном сценарии.