OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构( 二 )


2.通用仓储和缓存接口实现了泛型通用仓储接口,批量更新和删除方法基于最新的Entity Framework 7.0 RC1,为提高查询效率,查询方法全部返回IQueryable,包括分页查询,方便和其它实体连接后再筛选查询字段 。

OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构

文章插图
OnionArch - 采用DDD+CQRS+.Net 7.0实现的洋葱架构

文章插图
public interface IBaseRepository<TEntity> where TEntity : BaseEntity{Task<TEntity> Add(TEntity entity);Task AddRange(params TEntity[] entities);Task<TEntity> Update(TEntity entity);Task<int> UpdateRange(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls);Task<int> UpdateByPK(Guid Id, Expression<Func<SetPropertyCalls<TEntity>, SetPropertyCalls<TEntity>>> setPropertyCalls);Task<TEntity> Delete(TEntity entity);Task<int> DeleteRange(Expression<Func<TEntity, bool>> whereLambda);Task<int> DeleteByPK(Guid Id);Task<TEntity> DeleteByPK2(Guid Id);Task<TEntity> SelectByPK(Guid Id);IQueryable<TEntity> SelectRange<TOrder>(Expression<Func<TEntity, bool>> whereLambda, Expression<Func<TEntity, TOrder>> orderbyLambda, bool isAsc = true);Task<PagedResult<TEntity>> SelectPaged<TOrder>(Expression<Func<TEntity, bool>> whereLambda, PagedOption pageOption, Expression<Func<TEntity, TOrder>> orderbyLambda, bool isAsc = true);Task<bool> IsExist(Expression<Func<TEntity, bool>> whereLambda);}3.领域事件自动发布和保存在BaseDbContext文件的SaveChanges之前从实体中获取领域事件并发布领域事件和保存领域事件通知,以备后查 。
//所有包含领域事件的领域跟实体var haveEventEntities = domainRootEntities.Where(x => x.Entity.DomainEvents != null && x.Entity.DomainEvents.Any()).ToList();//所有的领域事件var domainEvents = haveEventEntities.SelectMany(x => x.Entity.DomainEvents).ToList();//根据领域事件生成领域事件通知var domainEventNotifications = new List<DomainEventNotification>();foreach (var domainEvent in domainEvents){domainEventNotifications.Add(new DomainEventNotification(nowTime, _currentUserService.UserId, domainEvent.EventType, JsonConvert.SerializeObject(domainEvent)));}//清除所有领域根实体的领域事件haveEventEntities.ForEach(entity => entity.Entity.ClearDomainEvents());//生成领域事件任务并执行var tasks = domainEvents.Select(async (domainEvent) =>{await _mediator.Publish(domainEvent);});await Task.WhenAll(tasks);//保存领域事件通知到数据表中DomainEventNotifications.AddRange(domainEventNotifications);领域事件发布和通知保存在底层实现 。开发人员不用关心领域事件发布和保存逻辑,只关注于领域事件的定义和处理即可 。
4.领域根实体审计信息自动记录在BaseDbContext文件的Savechanges之前对记录领域根实体的审计信息 。
//为每个继承AggregateRootEntity领域跟的实体的AddedBy,Added,LastModifiedBy,LastModified赋值            //为删除的实体生成实体删除领域事件
DateTime nowTime = DateTime.UtcNow;var domainRootEntities = ChangeTracker.Entries<AggregateRootEntity>();foreach (var entry in domainRootEntities){switch (entry.State){case EntityState.Added:entry.Entity.AddedBy = _currentUserService.UserId;entry.Entity.Added = nowTime;break;case EntityState.Modified:entry.Entity.LastModifiedBy = _currentUserService.UserId;entry.Entity.LastModified = nowTime;break;case EntityState.Deleted:EntityDeletedDomainEvent entityDeletedDomainEvent = new EntityDeletedDomainEvent(_currentUserService.UserId,entry.Entity.GetType().Name,entry.Entity.Id,JsonConvert.SerializeObject(entry.Entity));entry.Entity.AddDomainEvent(entityDeletedDomainEvent);break;}}

经验总结扩展阅读