MVC 在哪里放置需要数据库调用的验证
以 mvc 应用程序中这个简单、常见的场景为例:
当用户注册时,用户名需要是唯一的。
现在我已经阅读了很多有关项目结构、领域驱动设计、验证、mvc 等的内容,我对我的逻辑层感到满意:域(模型、核心)、域服务、控制器和视图。我可以通过向我的属性添加验证属性来确保用户名少于 10 个字符。故障将通过服务层返回控制器并进入视图。
但对于这个简单的场景,我坚持寻找调用堆栈的最佳解决方案 - 并对其进行了良好的测试,因为此验证需要调用数据库来检查所有其他用户名。
对我来说,这仍然是用户模型的验证问题。我真的希望能够创建一个自定义验证属性,以便在设置此属性时检查持久性以确保唯一性。
哇哦!直接调用数据库的域对象?我不确定这是一件坏事。我可以让 castle 将 IRespositories 注入到域中,对吧,这样就没有紧密耦合,毕竟它是定义数据接口的域。
有人对此有任何经验/意见吗?
Take this simple, common scenario in an mvc app:
When a user registers the username needs to be unique.
Now I've read lot about project structure, domain-driven design, validation, mvc etc and I'm happy about my logical layers: Domain (Model, Core), Domain Services, Controllers and Views. I can ensure e.g. the username is less than 10 characters by adding a validation attribute to my property. Failures will bubble up back through the service layer into the controller and out into the view.
But for this simple scenario I am stuck as to the best solution for the call stack - and have that tested well, since this validation needs to call the db to check all other usernames.
For me, this is still a validation concern of the User model. I would really like to be able to create a custom validation attribute, so that when this property is set, persistence is checked to ensure uniqueness.
Woah there! A domain object calling the db directly?? I'm not sure its a bad thing. I can have castle inject IRespositories into the Domain, right, so no tight coupling and after all its the Domain that defines the data interfaces.
Does anyone have any experience/ opinions on this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
错了……肯定不是。用户不应该知道兄弟姐妹。
如果用户是实体(它肯定不是),则验证唯一性是包含聚合根的责任。
如果它是聚合根,那么就没有太多选择(因为“没有任何东西保存”聚合根,它们是全局的) - 我使用存储库,尽管它们不应该具有域逻辑。但话又说回来 - 我不认为这种唯一性验证为 非常有价值(请参阅“并非所有规则都是生来平等的”)。
Wrong... It surely isn't. User shouldn't know about siblings.
If User is entity (which it quite surely isn't), validating uniqueness is responsibility of containing aggregate root.
If it's an aggregate root, then there isn't much options (because "nothing holds" an aggregate root, they are global) - I use repositories for that despite that they shouldn't have domain logic. but then again - I do not consider this kind of uniqueness validation as really valuable (see "All rules aren’t created equal").
最后,我坚持自己的直觉,认为这种行为应该在域中处理,而且似乎我并不孤单。
S#arp 架构的最新版本包含一个新的类验证属性 HasUniqueDomainSignature,与属性属性 DomainSignature 结合使用。当在 NHibernate.Vaidator 上调用 IsValid 时,公共服务定位器用于定位当前 NHibernate 会话并引用持久性。
这里对此进行了讨论。
In the end I've stuck to my gut feeling that this type of behaviour should be handled in the Domain, and it seems I am not alone.
The recent builds of S#arp Architecture have included a new Class Validation attribute HasUniqueDomainSignature, used in conjunction with Property attribute DomainSignature. When calling IsValid on NHibernate.Vaidator, the Common Service Locator is used to locate the current NHibernate session and persistence is referenced.
Here's a discussion on it.
如果您采用 DDD 路线,也许您应该考虑使用命令来启动域更改。然后域对象将不需要对它们进行验证:您可以根据命令执行所有必需的验证。
至于某些框架提供的基于属性的验证(例如 asp.net mvc),我真的很讨厌它。他们不应该关心您的领域模型。领域对象应始终处于有效状态,并自行维护其不变量。
If you are going DDD route perhaps you should consider using Commands for initiating domain changes. Then domain objects won't need to have validation on them: you may do all the required validation on command.
As for attribute-based validation, which some frameworks provide (like asp.net mvc), I really hate that. Your domain model shouldn't be their concern. The domain objects should always be in valid state, and maintain their invariants themselves.