Рекомендации по применению контрактов бизнес-правил к сущностям в Entity Framework - PullRequest
0 голосов
/ 12 мая 2011

С помощью коллеги мы нашли способ применять бизнес-правила к организации.Мы вводим субъекту договор, определяющий правила.Хотя само по себе это прекрасно работает, Entity Framework это не нравится.Причина в том, что мы ввели параметр в конструктор базовой сущности.EF не любит параметризованные конструкторы по уважительной причине.Вот некоторый код, который демонстрирует контракт:

     /// <summary>
    /// Class to define the Base Entity that will be inherited by All Entities with an Id of Guid
    /// </summary>
    public abstract class BaseEntity
    {
        protected BaseEntity(IEntityContract entityContract)
        {
            if(!entityContract.IsValid())
            {
                throw new EntityContractException();
            }
            DateCreated = DateTime.Now;
            DateModified = DateTime.Now;
        }

        /// <summary>
        /// Key Field for all entities
        /// </summary>
        /// 
        [Key, DatabaseGenerated(DatabaseGeneratedOption.Identity)]
        public Guid Id { get; set; }

        /// <summary>
        /// Date entity was created
        /// </summary>
        public DateTime DateCreated { get; set; }

        /// <summary>
        /// Last date Modified
        /// </summary>
        public DateTime DateModified { get; set; }
        /// <summary>
        /// keep track of Row Version used for concurrency
        /// </summary>
        [Timestamp]
        public Byte[] RowVersion { get; set; }

    }

    public class Address : BaseEntity
    {
        public Address(IEntityContract entityContract)
            : base(entityContract)
        {
        }

        public string Name { get; set; }
        public string Line1 { get; set; }
        public string Line2 { get; set; }
        public string City { get; set; }
        public string PostalCode { get; set; }

        public Guid RegionId { get; set; }
        public virtual Region Region { get; set; }


    }

    public abstract class BaseEntityContract<TEntity> : Interfaces.IEntityContract where TEntity : BaseEntity
    {
        private readonly List<string> _errors = new List<string>();
        private readonly List<BusinessRule<TEntity>> _businessRules = new List<BusinessRule<TEntity>>();

        public bool IsValid()
        {
            var contractIsvalid = true;

            foreach (var rule in _businessRules.Where(br => !br.Rule((TEntity)(Interfaces.IEntityContract)this)))
            {
                _errors.Add(rule.Description);
                contractIsvalid = false;
            }

            return contractIsvalid;
        }


        /// <summary>
        /// Adds a business rule to be used in validating the {TEntity} contract.
        /// </summary>
        /// <param name="rule">The function used to represent the business rule.</param>
        /// <param name="description">The descriptive message describing the rule.</param>
        protected void RegisterBusinessRule(Func<TEntity, bool> rule, string description)
        {
            _businessRules.Add(new BusinessRule<TEntity>(rule, description));
        }
    }


    public class AddressEntityContract : BaseEntityContract<Address>
    {
        public AddressEntityContract()
        {
            this.RegisterBusinessRule(a => a.Line1.length > 0, "Line 1 cannot be empty.");
        }
    }

Я знаю, что вы можете применить некоторую проверку непосредственно к свойствам сущности и через свободный API, но это кажется более постоянным, чем бизнес, связанный смне.Например, что касается данных, давайте предположим, что столбец описания может иметь длину 255 символов, но бизнесу необходимо только 100 символов.Мы можем определить начальные атрибуты, связанные с постоянством, во время создания базы данных / модели.Мне очень нравится идея контракта, но я не вижу, чтобы она работала с Entity Framework.Единственная другая мысль, которая у меня была, заключалась в том, чтобы контракты (или бизнес-класс) находились между предприятием и EF.Мой DAL передает объекты в класс Business Rules и, если все в порядке, передает их в мою службу или наоборот.Я надеюсь, что у кого-то есть лучший подход, чем этот, в отношении бизнес-правил, которые применяются к организации

1 Ответ

0 голосов
/ 13 мая 2011

У меня была пара мыслей об этом прошлой ночью.

Один из вариантов заключается в обработке правил внутри DTO, а не в сущностях домена. Это предполагает, что доменные сущности всегда действительны либо из приложения (через DTO), либо из Entity Framework (из хранилища данных).

Другой вариант заключается в том, чтобы рассматривать контракты как объекты и передавать их в Entity Framework, а затем вводить контракты в домен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...