当前位置: 首页 > news >正文

网站建设新规装配式建筑信息平台

网站建设新规,装配式建筑信息平台,企业做响应式网站好吗,手机网站一键生成appdotNET兄弟会 专注.Net开源技术及跨平台开发#xff01;致力于构建完善的.Net开放技术文库#xff01;为.Net爱好者提供学习交流家园#xff01;公众号 围绕DDD和ABP Framework两个核心技术#xff0c;后面还会陆续发布核心构件实现、综合案例实现系列文章#xff0c;敬请… dotNET兄弟会 专注.Net开源技术及跨平台开发致力于构建完善的.Net开放技术文库为.Net爱好者提供学习交流家园公众号  围绕DDD和ABP Framework两个核心技术后面还会陆续发布核心构件实现、综合案例实现系列文章敬请关注 ABP Framework 研习社QQ群726299208 ABP Framework 学习及实施DDD经验分享示例源码、电子书共享欢迎加入系列文章基于ABP落地领域驱动设计-01.全景图基于ABP落地领域驱动设计-02.聚合和聚合根的最佳实践和原则仓储仓储接口是一组集合的接口被领域层和应用层用来访问数据持久化系统数据库以读写业务对象业务对象通常是聚合。仓储的通用原则•在领域层中定义仓储接口在基础层中实现仓储接口比如EntityFrameworkCore项目或MongoDB项目•仓储不包含业务逻辑专注数据处理。•仓储接口应该保持 数据提供程序/ORM 独立性。举个例子仓储接口定义的方法不能返回 DbSet 对象因为该对象由 EF Core 提供如果使用 MongoDB 数据库则无法实现该接口。•为聚合根创建对应仓储而不是所有实体。因为子集合实体聚合应该通过聚合根访问。仓储中不包含领域逻辑虽然这个规则一开始看起来很好理解但在实际开发过程中很容易在不经意间将业务逻辑放到仓储中。示例从仓储中获取 inactive 状态的 Issueusing System; using System.Collections.Generic; using System.Threading.Tasks; using Volo.Abp.Domain.Repositories;namespace IssueTracking.Issues {public interface IIssueRepository:IRepositoryIssue,Guid{TaskListIssue GetInActiveIssuesAsync();} } IIssueRepository 继承 IRepositoryIssue,Guid 接口添加了 GetInActiveIssuesAsync() 方法。与之对应的聚合根类型是 Issue 类public class Issue:AggregateRootGuid,IHasCreationTime {public bool IsClosed{get;private set;}public Guid? AssignedUserId{get;private set;}public DateTime CreationTime{get;private set;}public DateTime? LastCommentTime{get;private set;} } 规则要求我们仓储不应该知道业务规则那么问题来了什么是 inactive Issue未激活的问题这是业务规则。为了更好地理解我们继续看看接口方法的实现using System; using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using IssueTracking.EntityFrameworkCore; using Microsoft.EntityFrameworkCore; using Volo.Abp.Domain.Repositories.EntityFrameworkCore; using Volo.Abp.EntityFrameworkCore;namespace IssumeTracking.Issues {public class EfCoreIssueRepository:EfCoreRepositoryIssueTrackingDbContext,Issue,Guid,IIssueRepository{public EfCoreIssueRepository(IDbContextProviderIssueTrackingDbContext dbContextProvider):base(dbContextProvider){}public async TaskListIssue GetInActiveIssueAsynce(){var daysAgo30DateTime.Now.Subtract(TimeSpan.FromDays(30));var dbSet await GetDbSetAsync();return await dbSet.Where(i//打开状态!i.IsClosed //无分配人i.AssingedUserId null //创建时间在30天前i.CreationTime daysAgo30 //没有评论或最后一次评论在30天前(i.LastCommentTime null || i.LastCommentTime daysAgo30)).ToListAsync();}} } 在 GetInActiveIssueAsynce 实现方法中对于未激活的Issue 这条业务规则需要满足条件打开状态、未分配给任何人、创建超过30天、最近30天没有评论。如果我们将业务规则隐含在仓储中当我们需要重复使用这个业务逻辑时问题就出现了。举个例子在 Issue 实体中希望添加一个方法 bool IsInActive()用于检测 Issue 是否未激活状态。看看如何实现public class Issue:AggregateRootGuid,IHasCreationTime {public bool IsClosed {get;private set;}public Guid? AssignedUserId{get;private set;}public DateTime CreationTiem{get;private set;}public DateTime? LastCommentTime{get;private set;}//...public bool IsInActive(){var daysAgo30DateTime.Now.Subtract(TimeSpan.FromDays(30));return//打开状态!IsClosed //无分配人AssignedUserId null //创建时间在30天前CreationTime daysAgo30 //无评论或最后一次评论在30天前(LastCommentTime null || LastCommentTime daysAgo30 );} } 我们不得不复制、粘贴、修改代码。如果对未激活的Issue 规则改变了怎么办我们应该记得同时更新这两个地方。这是业务逻辑重复代码的坏味道是相当危险的。这个问题的一个很好的解决方案就是规约。规约规约是一个命名的、可重用的、可组合的和可测试的类用于根据业务规则过滤领域对象。ABP框架提供了必要的基础设施以轻松创建规约并在你的应用程序代码中使用。让我们把 inactive Issue 非活动问题业务规则实现为一个规约类。using System; using System.Linq.Expressions; using Volo.Abp.Specifications;namespace IssueTracking.Issues {public class InActiveIssueSpecification:SpecificationIssue{public override ExpressionFuncIssue,bool ToExpression(){var daysAgo30DateTime.Now.Subtract(TimeSpan.FromDays(30));return i //打开状态!i.IsClosed //无分配人i.AssingedUserId null //创建时间超过30天i.CreationTime daysAgo30 //没有评论或最后评论超过30天(i.LastCommentTime null || i.LastCommentTime daysAgo30)}} } SpecificationT 基类可以帮助我们简单地创建规约类我们可以将仓储中的表达式移到规约中。现在可以在 Issue 实体和 EfCoreIssueRepository 类中使用 InActiveIssueSpecification 规约。在实体中使用规约Specification类提供了一个IsSatisfiedBy方法如果给定的对象实体满足该规范则返回true。我们可以重新编写Issue.IsInActive方法如下所示public class Issue:AggregateRootGuid,IHasCreationTime {public bool IsClosed{get;private set;}public Guid? AssignedUserId{get;private set;}public DateTime CreationTiem{get;private set;}public DateTime? LastCommentTime{get;private set;}//...public bool IsInActive(){return new InActiveIssueSpecification().IsSatisfiedBy(this);} } 创建一个 InActiveIssueSpecification 新实例使用其 IsSatisfiedBy 方法进行规约验证。在仓储中使用规约首先修改仓储接口public interface IIssueRepository:IRepositoryIssue,Guid {TaskListIssue GetIssuesAsync(ISpecificationIssue spec); } 将方法名 GetInActiveIssuesAsync 改为 GetIssuesAsync (命名更加简洁)接收一个规约对象参数。将规约判断的代码逻辑从仓储中移出之后我们不再需要定义不同的方法来获取不同条件下的Issue比如GetAssignedIssues(...) 获取已有分配人的问题列表GetLockedIssues(...) 获取已锁定问题列表 等。修改仓储的实现public class EfCoreIssueRepository:EfCoreRepositoryIssueTrackingDbContext,Issue,Guid,IIssueRepository {public EfCoreIssueRepository(IDbContextProviderIssueTrackingDbContext dbContextProvider):base(dbContextProvider){}public async TaskListIssue GetIssuesAsync(ISpecificationIssue spec){var dbSet await GetDbSetAsync();return await dbSet.Where(spec.ToExpresion()).ToListAsync();} } ToExpression()方法返回一个表达式可以直接作为 Where 方法的参数传递实现实体过滤。最后我们将规约实例传递给 GetIssuesAsync 方法:public class IssueAppServie : ApplciationService,IIssueAppService {private readonly IIssueRepository _issueRepository;public IssueAppService (IIssueRepository issueRepository){_issueRepository issueRepository;}public async Task DoItAsync(){var issues await _issueRepository.GetIssuesAsync(new InActiveIssueSpecification(););} } 默认仓储实际上你不需要创建自定义仓储就能使用规约。标准的IRepository 接口已经扩展 IQueryable 接口所以你可以直接使用标准的LINQ扩展方法。非常帅气public class IssueAppServie : ApplciationService,IIssueAppService {private readonly IRepositoryIssue,Guid _issueRepository;public IssueAppService (IRepositoryIssue,Guid issueRepository){_issueRepository issueRepository;}public async Task DoItAsync(){var queryable await _issueRepository.GetQueryableAsync();var issues AsyncExecuter.ToListAsync(queryable.Where(new InActiveIssueSpecification()));} } AsyncExecuter是ABP框架提供的一个工具类用于使用异步LINQ扩展方法比如这里的ToListAsync而不依赖于EF Core NuGet 包。组合规约规范的一个强大的地方是它们是可以组合使用的。假设我们有另一个规约当问题 Issue 处于指定里程碑中时返回true。public class MilestoneSpecification : SpecificationIssue {public Guid MilestoneId{get;}public MilestoneSpecification (Guid milestoneId){MilestoneId milestoneId;}public override ExpressionFuncIssue,bool ToExpression(){return i i.MilestoneId MilestoneId;} } 我们新定义了一个新的参数化规约和前面定义 InActiveIssueSpecification 不同。那么如何组合两个规约获取指定里程碑中未激活的 Issue问题呢public class IssueAppServie : ApplciationService,IIssueAppService {private readonly IRepositoryIssue,Guid _issueRepository;public IssueAppService (IRepositoryIssue,Guid issueRepository){_issueRepository issueRepository;}public async Task DoItAsync(Guid milesoneId){var queryable await _issueRepository.GetQueryableAsync();var issues AsyncExecuter.ToListAsync(queryable.Where(new InActiveIssueSpecification().Add(new MilestoneSpecification(milestoneId)).ToExpression()));} } 示例中使用 Add 扩展方法组合规约还有更多的扩展方法比如Or(...) AndNot(...)。学习帮助围绕DDD和ABP Framework两个核心技术后面还会陆续发布核心构件实现、综合案例实现系列文章敬请关注ABP Framework 研习社QQ群726299208 专注 ABP Framework 学习及DDD实施经验分享示例源码、电子书共享欢迎加入
http://www.sadfv.cn/news/209018/

相关文章:

  • 网站右侧浮动导航wordpress js 钩子
  • 龙湖什么网站做宣传在五八同城做网站多少钱
  • 网站程序开发制作十大品牌建设银行网站官方网站
  • 如何评价一个网站做的好不好汉中今天确诊名单
  • 单页网站模板做seowordpress之家
  • 对网站开发流程的了解云南澄江县建设局网站
  • 优秀排版设计网站合肥网站开发
  • seo网站内容更新孝感网站seo
  • 英语网站online网站开发到上线需要多久
  • 门户网站建设工具视觉设计软件
  • 事业单位网站建设费科目sem推广竞价托管公司
  • 贵阳网站制作维护平凉网站建设平凉
  • 山东建设信息网站永久免费网站怎么建
  • 提高网站搜索排名大学生建设什么网站好
  • 企业网站设计制作收费WordPress评论回复提醒勾选
  • 全球网站排名前100什么网站是用php做的
  • 网站推广工作总结网页传奇游戏攻略
  • 如何建立一个手机网站罗湖区住房和建设局网站
  • 网站开发与维护实训总结怎么样备份网站数据库
  • 网站页面切换效果河北中冶润丰建设股份有限公司网站
  • 服装网站推广策划书做一个自己的网站
  • 保健品网站建设背景百度seo泛解析代发排名
  • 图书馆网站建设情况说明个人开店的电商平台
  • 保险公司官方网站智慧团建系统登录
  • 迁安做网站中的cms润强php做调查问卷网站
  • 基层政权和社区建设司网站wordpress转dedecms
  • 全球访问量最大的10个网站定制做网站费用
  • 国内开源平台商城网站 没有什么文章 怎样优化
  • 企业网站空间购买无极电影网在线观看完整版
  • 免费网站免费进入在线哈尔滨小程序建设