【发布时间】:2021-10-11 11:36:48
【问题描述】:
我正在处理的问题是如何让我的控制器免于查询真正应该是基础架构而不是应用程序关注的逻辑。
下面是 Command 和 CommandHandler 的示例。顺便说一句,我正在使用 MediatR。
如您所见,Command 包含一些过滤器(我认为没问题,不违反 CQRS),但 Command Handler 中包含太多逻辑。我不确定这是处理程序必须处理的事情。
GetMatchesCommand
public class GetMatchesCommand : IRequest<IEnumerable<MatchDto>>
{
public Tuple<DateTime, DateTime> TimeInterval { get; set; }
public Guid? Location { get; set; }
public Guid? Team { get; set; }
public Guid? Player { get; set; }
}
GetMatchesCommandHandler
public class GetMatchesCommandHandler : IRequestHandler<GetMatchesCommand, IEnumerable<MatchDto>>
{
public async Task<IEnumerable<MatchDto>> Handle(GetMatchesCommand request, CancellationToken cancellationToken)
{
Expression<Func<Match, bool>> filterExpression = default;
// Build the filter expression
// Filter by interval
if (request.TimeInterval != null)
filterExpression.ConcatAnd(
m => m.StartTime >= request.TimeInterval.Item1
&& (m.StartTime + m.Duration) <= request.TimeInterval.Item2);
// Filter by team
if (request.Team != null)
filterExpression.ConcatAnd(
m => m.Team1Id == request.Team
|| m.Team2Id == request.Team);
// Filter by player
if (request.Player != null)
filterExpression.ConcatAnd(
m => m.Team1.Players.Any(p => p.Id == request.Player)
|| m.Team2.Players.Any(p => p.Id == request.Player));
var query = _dbContext.Matches
.Include(m => m.Team1).ThenInclude(t => t.Players)
.Include(m => m.Team2).ThenInclude(t => t.Players);
// if there are any filters, apply them
if(filterExpression != null)
{
query.Where(filterExpression);
}
var matches = query.ToListAsync();
return _mapper.Map<List<MatchDto>>(matches);
}
}
我知道存储库模式可能适合这种情况,但是,正确的做法是什么?老实说,拥有_matchesRepo.Get(interval, team, player, location) 并将此逻辑移到那里似乎并不是一个非常聪明的方法...
有人可以给我一个建议吗?提前谢谢!
【问题讨论】:
-
当然我们可以做完整的企业,但你的目标是什么?如果我们遵守 80/20 规则,也就是说,您可以通过 20% 的努力获得 80% 的结果,而通过 80% 的努力获得剩下的 20% 的结果——这值得吗?将过滤逻辑提取到某种表达式构建器中,以便可以单独对其进行测试并使用它来完成。
-
实际问题是我有多个这样的命令处理程序。顺便说一句,什么是表达式生成器?我认为这对我来说是新事物。我要去寻找那个。如果你能分享一些关于这些的资源,将不胜感激
-
如果这些表达式在处理程序之间不一样,那么你真的没有什么可提取的。我可以通过将表达式提取到一个方法中来简化这个,这样你就可以写
var filterExpression = GetExpression(request);
标签: c# .net cqrs clean-architecture mediatr