分享

DDD领域驱动设计初探(7)(上):Web层的搭建

 weijianian 2016-08-07


来源:懒得安分

链接:http://www.cnblogs.com/landeanfen/p/4920577.html


一、UI层介绍


在DDD里面,UI层的设计也分为BS和CS,本篇还是以Web为例来说明。我们的Web采用的是MVC+bootstrap的架构。Table组件使用的是bootstrap table,之所以用它是因为它的API比较全,并且博主觉得它的风格适用于各种类型的设备,无论是PC端还是手机端都都能很好的兼容各种浏览器。


二、代码示例


上篇完成了WCF的设计代码,但是具体的业务逻辑的代码还没有,我们先来实现具体业务的CURD代码。


1、WCF代码


1.1 WCF服务业务接口代码

/// 

/// 权限管理模块接口契约

/// 

[ServiceContract]

[ServiceInterface]

public interface IPowerManageWCFService

{

    #region 用户管理

    [OperationContract]

    List GetUsers(ExpressionNode expressionNode);

    [OperationContract]

    DTO_TB_USERS AddUser(DTO_TB_USERS oUser);

    [OperationContract]

    bool DeleteUser(DTO_TB_USERS oUser);

    [OperationContract]

    bool DeleteUserByLamada(ExpressionNode expressionNode);

    [OperationContract]

    bool UpdateUser(DTO_TB_USERS oUser);

    #endregion

    #region 部门管理

    [OperationContract]

    List GetDepartments(ExpressionNode expressionNode);

    [OperationContract]

    DTO_TB_DEPARTMENT AddDepartment(DTO_TB_DEPARTMENT oDept);

    [OperationContract]

    bool DeleteDepartment(DTO_TB_DEPARTMENT oDept);

    [OperationContract]

    bool DeleteDeptByLamada(ExpressionNode expressionNode);

    [OperationContract]

    bool UpdateDepartment(DTO_TB_DEPARTMENT oDept);

    #endregion

    #region 角色管理

    [OperationContract]

    List GetRoles(ExpressionNode expressionNode);

    [OperationContract]

    DTO_TB_ROLE AddRole(DTO_TB_ROLE oRole);

    #endregion

    #region 菜单管理

    [OperationContract]

    List GetMenus(ExpressionNode expressionNode);

    [OperationContract]

    DTO_TB_MENU AddMenu(DTO_TB_MENU oMenu);

    #endregion

}


1.2 WCF接口实现代码:


[ServiceClass]

    public class PowerManageWCFService :BaseService, IPowerManageWCFService

    {

        #region Fields

        [Import]

        private IUserRepository userRepository { get; set; }

        [Import]

        private IDepartmentRepository departmentRepository { get; set; }

        [Import]

        private IRoleRepository roleRepository { get; set; }

        [Import]

        private IMenuRepository menuRepository { get; set; } 

        #endregion

 

        #region Constust

        public PowerManageWCFService()

        {

        }

        #endregion

        #region WCF服务接口实现

        #region 用户管理

//这里参数为什么不直接用Expression>这种类型,是因为Expression不支持序列化,无法用于WCF数据的传递

        public List GetUsers(ExpressionNode expressionNode)

        {

            Expressionbool>> selector = null;

            if (expressionNode != null)

            {

                selector = expressionNode.ToExpressionbool>>();

            }

            var lstRes = base.GetDtoByLamada(userRepository, selector);

            return lstRes;

        }

 

        public DTO_TB_USERS AddUser(DTO_TB_USERS oUser)

        {

            return base.AddDto(userRepository, oUser);

        }

 

        public bool DeleteUser(DTO_TB_USERS oUser)

        {

            var bRes = false;

            try

            {

                base.DeleteDto(userRepository, oUser);

                bRes = true;

            }

            catch

            { 

 

            }

            return bRes;

        }

 

        public bool DeleteUserByLamada(ExpressionNode expressionNode)

        {

            Expressionbool>> selector = null;

            if (expressionNode != null)

            {

                selector = expressionNode.ToExpressionbool>>();

            }

            var bRes = false;

            try

            {

                base.DeleteDto(userRepository, selector);

                bRes = true;

            }

            catch

            {

 

            }

            return bRes;

        }

 

        public bool UpdateUser(DTO_TB_USERS oUser)

        {

            var bRes = false;

            try

            {

                base.UpdateDto(userRepository, oUser);

                bRes = true;

            }

            catch

            {

            }

            return bRes;

        }

        #endregion

 

        #region 部门管理

        public List GetDepartments(ExpressionNode expressionNode)

        {

            Expressionbool>> selector = null;

            if (expressionNode != null)

            {

                selector = expressionNode.ToExpressionbool>>();

            }

            return base.GetDtoByLamada(departmentRepository, selector);

        }

        public DTO_TB_DEPARTMENT AddDepartment(DTO_TB_DEPARTMENT oDept)

        {

            return base.AddDto(departmentRepository, oDept);

        }

        public bool DeleteDepartment(DTO_TB_DEPARTMENT oDept)

        {

            var bRes = false;

            try

            {

                base.DeleteDto(departmentRepository, oDept);

                bRes = true;

            }

            catch

            {  }

            return bRes;

        }

 

        public bool DeleteDeptByLamada(ExpressionNode expressionNode)

        {

            Expressionbool>> selector = null;

            if (expressionNode != null)

            {

                selector = expressionNode.ToExpressionbool>>();

            }

            var bRes = false;

            try

            {

                base.DeleteDto(departmentRepository, selector);

                bRes = true;

            }

            catch

            {

            }

            return bRes;

        }

 

        public bool UpdateDepartment(DTO_TB_DEPARTMENT oDept)

        {

            var bRes = false;

            try

            {

                base.UpdateDto(departmentRepository, oDept);

                bRes = true;

            }

            catch

            {  }

            return bRes;

        }

        #endregion

 

        #region 角色管理

        public List GetRoles(ExpressionNode expressionNode)

        {

            Expressionbool>> selector = null;

            if (expressionNode != null)

            {

                selector = expressionNode.ToExpressionbool>>();

            }

            return base.GetDtoByLamada(roleRepository, selector);

        }

 

        public DTO_TB_ROLE AddRole(DTO_TB_ROLE oRole)

        {

            return base.AddDto(roleRepository, oRole);

        }

        #endregion

        #region 菜单管理

        public List GetMenus(ExpressionNode expressionNode)

        {

            Expressionbool>> selector = null;

            if (expressionNode != null)

            {

                selector = expressionNode.ToExpressionbool>>();

            }

            return base.GetDtoByLamada(menuRepository, selector);

        }

        public DTO_TB_MENU AddMenu(DTO_TB_MENU oMenu)

        {

            return base.AddDto(menuRepository, oMenu);

        }

        #endregion

        #endregion

    }


这里要说明一点,在通过lamada表达式查询的方法里面为什么不直接用Expression>这种类型,而要使用ExpressionNode这种类型的变量呢?


这是因为Expression不支持序列化,无法用于WCF数据的传递。ExpressionNode这个对象的使用需要添加Serialize.Linq这个dll的引用,还好有我们神奇的NuGet,让我们再也不用去网上找一大堆的dll了。



我们公用的增删改查封装到了BaseService这个父类里面。


1.3 BaseService代码


public class BaseService

    {

        #region Fields

        private bool bInitAutoMapper = false;

        #endregion

        #region Construct 

        public BaseService()

        {

            //注册MEF

            Regisgter.regisgter().ComposeParts(this);

        }

        #endregion

        #region 查询

        /// 通用单表查询方法

        /// DTOmodel

        /// 领域模型

        /// 需要传过来的仓储接口对象

        /// 前端传过来的lamada表达式

        public List GetDtoByLamada(IRepository oRepository, Expressionbool>> selector = null)

            where DomainModel : AggregateRoot

            where DtoModel : Dto_BaseModel

        {

            InitAutoMapper();

            if (selector == null)

            {

                var lstDomainModel = oRepository.Entities.ToList();

                return Mapper.Map, List>(lstDomainModel);

            }       

//得到从Web传过来和DTOModel相关的lamaba表达式的委托

            Funcbool> match = selector.Compile();

//创建映射Expression的委托

            Func mapper = AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(Mapper.Engine).Compile();

//得到领域Model相关的lamada

            Expressionbool>> lamada = ef_t => match(mapper(ef_t));

            List list = oRepository.Find(lamada).ToList();

            return Mapper.Map, List>(list);

        } 

        #endregion

 

        #region 新增

        public DtoModel AddDto(IRepository oRepository, DtoModel oDtoModel)

            where DomainModel : AggregateRoot

            where DtoModel : Dto_BaseModel

        {

            InitAutoMapper();

            var oDomain = Mapper.Map(oDtoModel);

            oRepository.Insert(oDomain);

            return Mapper.Map(oDomain);

        }

        #endregion

 

        #region 删除

        public int DeleteDto(IRepository oRepository, DtoModel oDtoModel)

            where DomainModel : AggregateRoot

            where DtoModel : Dto_BaseModel

        {

            InitAutoMapper();

            var oDomain = Mapper.Map(oDtoModel);

            return oRepository.Delete(oDomain);

        }

 

        public int DeleteDto(IRepository oRepository, Expressionbool>> selector = null)

            where DomainModel : AggregateRoot

            where DtoModel : Dto_BaseModel

        {

            InitAutoMapper();

            if (selector == null)

            {

                return 0;

            }

            

//得到从Web传过来和DTOModel相关的lamaba表达式的委托

            Funcbool> match = selector.Compile();

            

//创建映射Expression的委托

            Func mapper = AutoMapper.QueryableExtensions.Extensions.CreateMapExpression(Mapper.Engine).Compile();

            

//得到领域Model相关的lamada

            Expressionbool>> lamada = ef_t => match(mapper(ef_t));

            return oRepository.Delete(lamada);

        } 

        #endregion

 

        #region 更新

        public void UpdateDto(IRepository oRepository, DtoModel oDtoModel)

            where DomainModel : AggregateRoot

            where DtoModel : Dto_BaseModel

        {

            InitAutoMapper();

            var oDomain = Mapper.Map(oDtoModel);

            oRepository.Update(oDomain);

        }

        #endregion

 

        #region Private

        private void InitAutoMapper()

        {

            var oType = Mapper.FindTypeMapFor();

            if (oType==null)

            {

                Mapper.CreateMap();

                Mapper.CreateMap();

            }

        }

        #endregion

    }


这个父类主要做了两件事:一是MEF的初始化;二是通用增删改查的实现。所有dto对象和领域model的映射都在这里统一管理。


2、UI层代码


UI层里面,为了更好分离代码,我们引入了接口编程的机制,引入了ESTM.Web.IBLL和ESTM.Web.BLL两个项目,如图:



为什么要有这么一个接口层?之前 MEF实现设计上的“松耦合”(终结篇:面向接口编程)这篇已经做过介绍,对面向接口编程不了解的朋友可以看看。


2.1 ESTM.Web.IBLL代码


这个dll主要定义接口规则。


public interface IPowerManager

   {

       List GetUsers(Expressionbool>> selector = null);

 

       DTO_TB_USERS AddUser(DTO_TB_USERS oUser);

 

       bool DeleteUser(DTO_TB_USERS oUser);

 

       bool UpdateUser(DTO_TB_USERS oUser);

 

       bool DeleteUser(Expressionbool>> selector = null);

 

       List GetDepartments(Expressionbool>> selector = null);

 

       DTO_TB_DEPARTMENT AddDepartment(DTO_TB_DEPARTMENT oDept);

 

       bool DeleteDepartment(DTO_TB_DEPARTMENT oDept);

 

       bool DeleteDepartment(Expressionbool>> selector = null);

 

       bool UpdateDepartment(DTO_TB_DEPARTMENT oDept);

 

       List GetRoles(Expressionbool>> selector = null);

 

       List GetMenus(Expressionbool>> selector = null);

 

   }




    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多