来源:懒得安分 链接: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); }
|