Как создать правило проверки с помощью 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

Вы также можете абстрагировать некоторые из этих кодов, чтобы упростить их использование в вашем конкретном сценарии.

Другие вопросы по тегам