zoukankan      html  css  js  c++  java
  • DDD领域驱动设计之领域基础设施层

    1、DDD领域驱动设计实践篇之如何提取模型

    2、DDD领域驱动设计之聚合、实体、值对象

    其实这里说的基础设施层只是领域层的一些接口和基类而已,没有其他的如日子工具等代码,仅仅是为了说明领域层的一些基础问题

    1、领域事件简单实现代码,都是来至ASP.NET设计模式书中的代码

    namespace DDD.Infrastructure.Domain.Events
    {
        public interface IDomainEvent
        {
        }
    }
    
    namespace DDD.Infrastructure.Domain.Events
    {
        public interface IDomainEventHandler<T> : IDomainEventHandler
            where T : IDomainEvent
        {
            void Handle(T e);
        }
    
        public interface IDomainEventHandler
        {
            
        }
    
    }
    namespace DDD.Infrastructure.Domain.Events
    {
        public interface IDomainEventHandlerFactory
        {
            IEnumerable<IDomainEventHandler<T>> GetDomainEventHandlersFor<T>(T domainEvent)
                                                                    where T : IDomainEvent;
        }
    
    }
    
    namespace DDD.Infrastructure.Domain.Events
    {
        public class StructureMapDomainEventHandlerFactory : IDomainEventHandlerFactory
        {
            public IEnumerable<IDomainEventHandler<T>> GetDomainEventHandlersFor<T>
                                                  (T domainEvent) where T : IDomainEvent
            {
                return ObjectFactory.GetAllInstances<IDomainEventHandler<T>>();
            }
        }
    
    }
    
    namespace DDD.Infrastructure.Domain.Events
    {
        public static class DomainEvents
        {
            public static IDomainEventHandlerFactory DomainEventHandlerFactory { get; set; }
    
            public static void Raise<T>(T domainEvent) where T : IDomainEvent
            {
                var handlers = DomainEventHandlerFactory.GetDomainEventHandlersFor(domainEvent);
                foreach (var item in handlers)
                {
                    item.Handle(domainEvent);
                }
            }
        }
    }

    2、领域层接口代码,很多都是来至MS NLayer代码和google code

    namespace DDD.Infrastructure.Domain
    {
        public interface IEntity<out TId>
        {
            TId Id { get; }
        }
    }
    
    namespace DDD.Infrastructure.Domain
    {
        public interface IAggregateRoot : IAggregateRoot<string>
        {
        }
    
        public interface IAggregateRoot<out TId> : IEntity<TId>
        {
        }
    }
    
    namespace DDD.Infrastructure.Domain
    {
        public abstract class EntityBase : EntityBase<string>
        {
            protected EntityBase()
                :this(null)
            {
            }
    
            protected EntityBase(string id)
            {
                this.Id = id;
            }
    
            public override string Id
            {
                get
                {
                    return base.Id;
                }
                set
                {
                    base.Id = value;
                    if (string.IsNullOrEmpty(this.Id))
                    {
                        this.Id = EntityBase.NewId();
                    }
                }
            }
    
            public static string NewId()
            {
                return Guid.NewGuid().ToString("N");
            }
        }
    
        public abstract class EntityBase<TId> : IEntity<TId>
        {
            public virtual TId Id 
            { 
                get;
                set;
            }
    
            public virtual IEnumerable<BusinessRule> Validate()
            {
                return new BusinessRule[] { };
            }
    
            public override bool Equals(object entity)
            {
                return entity != null
                   && entity is EntityBase<TId>
                   && this == (EntityBase<TId>)entity;
            }
    
            public override int GetHashCode()
            {
                return this.Id.GetHashCode();
            }
    
            public static bool operator ==(EntityBase<TId> entity1, EntityBase<TId> entity2)
            {
                if ((object)entity1 == null && (object)entity2 == null)
                {
                    return true;
                }
    
                if ((object)entity1 == null || (object)entity2 == null)
                {
                    return false;
                }
    
                if (entity1.Id.ToString() == entity2.Id.ToString())
                {
                    return true;
                }
    
                return false;
            }
    
            public static bool operator !=(EntityBase<TId> entity1, EntityBase<TId> entity2)
            {
                return (!(entity1 == entity2));
            }
        }
    
    }
    
    namespace DDD.Infrastructure.Domain
    {
        public interface IRepository<TEntity> : IRepository<TEntity, string>
             where TEntity : IAggregateRoot
        {
        }
    
        public interface IRepository<TEntity, in TId> 
            where TEntity : IAggregateRoot<TId>
        {
            void Modify(TEntity entity);
            void Add(TEntity entity);
            void Remove(TId id);
    
            IQueryable<TEntity> Where(Expression<Func<TEntity, bool>> predicate);
            IQueryable<TEntity> All();
            TEntity Find(TId id);
        }
    }
    
    namespace DDD.Infrastructure.Domain
    {
        public class BusinessRule
        {
            private string _property;
            private string _rule;
    
            public BusinessRule(string rule)
            {
                this._rule = rule;
            }
    
            public BusinessRule(string property, string rule)
            {
                this._property = property;
                this._rule = rule;
            }
    
            public string Property
            {
                get { return _property; }
                set { _property = value; }
            }
    
            public string Rule
            {
                get { return _rule; }
                set { _rule = value; }
            }
        }
    
    }
    
    namespace DDD.Infrastructure.Domain
    {
        /// <summary>
        /// Abstract Base Class for Value Objects
        /// Based on CodeCamp Server codebase http://code.google.com/p/codecampserver
        /// </summary>
        /// <typeparam name="TObject">The type of the object.</typeparam>
        [Serializable]
        public class ValueObject<TObject> : IEquatable<TObject> where TObject : class
        {
    
            /// <summary>
            /// Implements the operator ==.
            /// </summary>
            /// <param name="left">The left.</param>
            /// <param name="right">The right.</param>
            /// <returns>The result of the operator.</returns>
            public static bool operator ==(ValueObject<TObject> left, ValueObject<TObject> right)
            {
                if (ReferenceEquals(left, null))
                    return ReferenceEquals(right, null);
    
                return left.Equals(right);
            }
    
            /// <summary>
            /// Implements the operator !=.
            /// </summary>
            /// <param name="left">The left.</param>
            /// <param name="right">The right.</param>
            /// <returns>The result of the operator.</returns>
            public static bool operator !=(ValueObject<TObject> left, ValueObject<TObject> right)
            {
                return !(left == right);
            }
    
            /// <summary>
            /// Equalses the specified candidate.
            /// </summary>
            /// <param name="candidate">The candidate.</param>
            /// <returns>
            /// true if the current object is equal to the <paramref name="candidate"/> parameter; otherwise, false.
            /// </returns>
            public override bool Equals(object candidate)
            {
                if (candidate == null)
                    return false;
    
                var other = candidate as TObject;
    
                return Equals(other);
            }
    
            /// <summary>
            /// Indicates whether the current object is equal to another object of the same type.
            /// </summary>
            /// <param name="other">An object to compare with this object.</param>
            /// <returns>
            /// true if the current object is equal to the <paramref name="other"/> parameter; otherwise, false.
            /// </returns>
            public virtual bool Equals(TObject other)
            {
                if (other == null)
                    return false;
    
                Type t = GetType();
    
                FieldInfo[] fields = t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public);
    
                foreach (FieldInfo field in fields)
                {
                    object otherValue = field.GetValue(other);
                    object thisValue = field.GetValue(this);
    
                    //if the value is null...
                    if (otherValue == null)
                    {
                        if (thisValue != null)
                            return false;
                    }
                    //if the value is a datetime-related type...
                    else if ((typeof(DateTime).IsAssignableFrom(field.FieldType)) ||
                             ((typeof(DateTime?).IsAssignableFrom(field.FieldType))))
                    {
                        string dateString1 = ((DateTime)otherValue).ToLongDateString();
                        string dateString2 = ((DateTime)thisValue).ToLongDateString();
                        if (!dateString1.Equals(dateString2))
                        {
                            return false;
                        }
                        continue;
                    }
                    //if the value is any collection...
                    else if (typeof(IEnumerable).IsAssignableFrom(field.FieldType))
                    {
                        IEnumerable otherEnumerable = (IEnumerable)otherValue;
                        IEnumerable thisEnumerable = (IEnumerable)thisValue;
    
                        if (!otherEnumerable.Cast<object>().SequenceEqual(thisEnumerable.Cast<object>()))
                            return false;
                    }
                    //if we get this far, just compare the two values...
                    else if (!otherValue.Equals(thisValue))
                        return false;
                }
    
                return true;
            }
    
            /// <summary>
            /// Serves as a hash function for a particular type.
            /// </summary>
            /// <returns>
            /// A hash code for the current <see cref="T:System.Object"/>.
            /// </returns>
            public override int GetHashCode()
            {
                IEnumerable<FieldInfo> fields = GetFields();
    
                const int startValue = 17;
                const int multiplier = 59;
    
                int hashCode = startValue;
    
                foreach (FieldInfo field in fields)
                {
                    object value = field.GetValue(this);
    
                    if (value != null)
                        hashCode = hashCode * multiplier + value.GetHashCode();
                }
    
                return hashCode;
            }
    
            /// <summary>
            /// Gets the fields.
            /// </summary>
            /// <returns>FieldInfo collection</returns>
            private IEnumerable<FieldInfo> GetFields()
            {
                Type t = GetType();
    
                var fields = new List<FieldInfo>();
    
                while (t != typeof(object))
                {
                    fields.AddRange(t.GetFields(BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public));
    
                    t = t.BaseType;
                }
    
                return fields;
            }
    
        }
    }
    

      

  • 相关阅读:
    重新认识布局:html和body元素
    重新认识布局:3d空间中的css盒子
    重新认识布局:百分比单位
    重新认识布局:标准流,浮动,定位的关系
    Redis(1.7)Redis高可用架构与数据库交互(理论篇)
    C++: 模块定义文件声明(.def)的使用
    HttpListener supports SSL only for localhost? install certificate
    跨域请求引起的 OPTIONS request
    html 浏览器自动加上 标签的详解
    c# HttpServer 的使用
  • 原文地址:https://www.cnblogs.com/liubiaocai/p/3938230.html
Copyright © 2011-2022 走看看