所以我在我们的应用程序中喜欢CQRS的概念,主要是因为我们已经支持事件采购(从概念上讲,不遵循您在那里看到的任何处方).然而,看起来CQRS似乎是面向大数据,最终的一致性,那种事情.我们总是成为一个关系数据库应用程序,所以我不确定它是否合适.
我也有顾虑,因为我认为我需要在我的应用层中做一些特殊的事情.在进行读取时,我需要强制执行安全性和过滤数据,这些是传统上在应用程序层中实现的内容.
我的第一个问题是,我的应用程序是否合适(传统的MVC /关系数据库应用程序)?或者使用传统的应用层并使用DTO Mapper更有意义吗?
我的第二个问题是,从传统的应用程序层向域模型发出命令是否有意义?我喜欢命令/命令处理程序和事件的想法.
让我澄清一下我的问题.我担心与授权相关的数据过滤.当用户请求数据时,必须有一个过滤器,通过将它们全部一起删除(因此它们不会返回给调用者),隐藏值或对数据应用掩码来限制对某些数据元素的访问.在一个人为的例子中,对于社会安全号码,提出请求的用户可能只能看到最后4个号码,因此结果看起来像### - ## - 1234.
我的断言是这个责任在Application层中.我认为这是一个方面,其中对查询或命令的所有响应都必须通过此过滤器机制.这是我的CQRS naivity所经历的地方,也许是命令永远不会返回数据,只是指向通过读取模型查找的数据的指针?
谢谢!
首先:CQRS和关系数据库不会相互排斥.在高级方案中,将基于SQL的DB替换为其他存储方式可能是有意义的,但CQRS作为一个概念并不关心持久性机制.
对于依赖于角色和/或用户的多个视图,精简读取层应该提供多个结果集:
一个包含有权访问该信息的用户的完整SSN.
对于未被授权查看该信息的用户而言是另一个用户
...
这些可以存储在单独的数据存储中,但如果使用单个基于SQL的数据库,也可以通过SQL视图提供它们.
在CQRS中,应用程序服务仍以命令处理程序的形式存在.这些可以嵌套,即首先处理授权,然后将命令发布到包含的命令处理程序.
public class AuthorizationHandler { public CrmAuthorizationService(CrmCommandHandler handler) { _next = handler; } public void Handle(SomeCommand c) { if (authorized) _next.Handle(c); } } // Usage: var handler = new CrmAuthorizationService(new CrmCommandHandler()); bus.Register(handler.Handle);
这样,您可以嵌套多个处理程序,例如作为REST信封,用于记录,事务等.
回答你的问题:
第一: CQRS是否适合您的应用?没有人真正深入了解具体要求就无法分辨.仅仅因为你使用MVC和关系数据库并不意味着什么在CQRS的利弊.
第二:是的,在某些情况下,让您的应用程序层以经典方式与客户端交互并处理诸如身份验证,授权等内容,然后在内部发出命令是有意义的.当在应用程序之上放置基于MVC的UI或REST API时,这非常有用.
更新以回应评论:
在一个理想的,纯粹的CQRS场景中,Sally会为每个视图提供自己的非规范化数据,例如NoSQL DB中的几个文档,名为CustomerListForSally,CustomerDetailsForSally等.这些文档中包含了她允许看到的内容.
一旦她获得晋升 - 这将是一个重要的领域事件 - 所有她的非规范化数据将自动被覆盖,并扩展到包含她现在可以看到的内容.
当然,我们必须保持合理和务实,但这个理想应该是我们前进的大方向.
实际上,您可能拥有某种用户/角色或基于用户/组的系统.为了能够查看敏感信息,您必须是特定角色或组的成员.这些中的每一个都可以具有其定义的视图和命令集.这不需要是deoalized数据它可以像SQL-Views一样简单:
CustomerDetailsForSupportStaff
具有未屏蔽SSN的CustomerDetailsForSupportExecutive
CustomerListForSupportStaff
CustomerListForSupportExecutive,包含客户收入总计
等等