加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > asp.Net > 正文

asp.net-mvc – 纯粹的DDD方法可以和NHibernate一起使用吗?

发布时间:2020-12-16 03:49:17 所属栏目:asp.Net 来源:网络整理
导读:我一直在阅读DDD,我很困惑在使用像NHibernate这样的ORM时它会如何适应. 现在我有一个.NET MVC应用程序与相当“胖”的控制器,我正在试图弄清楚如何最好地解决这个问题.将此业务逻辑移动到模型层中是最好的方法,但我不确定如何做到这一点. 我的应用程序已设置
我一直在阅读DDD,我很困惑在使用像NHibernate这样的ORM时它会如何适应.

现在我有一个.NET MVC应用程序与相当“胖”的控制器,我正在试图弄清楚如何最好地解决这个问题.将此业务逻辑移动到模型层中是最好的方法,但我不确定如何做到这一点.

我的应用程序已设置好,以便NHibernate的会话由HttpModule管理(获取会话/事务),这是由返回实体对象的存储库使用的(Think S#arp arch …结果是真的重复了一个很多他们的功能).这些存储库由DataServices使用,它现在只是存储库的包装(它们之间的一对一映射,例如UserDataService采用UserRepository,或实际上是存储库).这些DataServices现在只确保在保存/更新时检查装饰实体类的数据注释.

通过这种方式,我的实体实际上只是数据对象,但不包含任何真实的逻辑.虽然我可以在实体类中放置一些东西(例如“批准”方法),当该操作需要执行诸如发送电子邮件或触摸其他非相关对象之类的操作时,或者,例如,检查是否有任何用户在批准之前拥有相同的电子邮件等,那么实体将需要访问其他存储库等.用IoC注入这些用户不适用于NHibernate,所以你必须使用工厂模式我假设得到这些.我不知道你怎么会在测试中嘲笑那些.

因此,我认为,下一个最合乎逻辑的方法是,每个控制器基本上都有一个服务,并将当前控制器中正在完成的所有工作提取到每个服务的方法中.我认为这可以打破DDD的想法,因为逻辑现在不再包含在实际的模型对象中.

另一种观察方式我认为这些服务中的每一个都与它所使用的数据对象形成一个单一的模型(数据存储区域的分离和对其进行操作的逻辑),但我只是想看看其他什么正在使用像NHIB这样的ORM来解决DDD的“胖控制器”问题,它通过返回填充的数据对象和存储库模型来工作.

更新
我想我的问题是我在看这个问题:NHibernate似乎把业务对象(实体)放在堆栈的底部,然后这些存储库依赖于它们.服务器使用存储库,这些服务可以使用多个存储库和其他服务(电子邮件,文件访问)来执行操作.即:App>服务>存储库>业务对象

我正在阅读的纯DDD方法似乎反映了Active Record偏差,其中CRUD函数存在于业务对象中(我直接调用User.Delete而不是来自服务的Repository.Delete),以及实际的业务对象句柄在这种情况下需要完成的事情的逻辑(如通过电子邮件发送用户,删除属于用户的文件等).即应用> (服务)> Business Objects>库

使用NHibernate,看起来我会更好地使用NHibernate函数的第一种方法,并且我正在寻找对我的逻辑的确认.或者如果我感到困惑,可以对这种分层方法如何工作进行一些澄清.我的理解是,如果我有一个“批准”方法来更新用户模型,保留它,并且让我们说,给少数人发电子邮件,这个方法应该放在用户实体对象上,但允许适当的IoC,所以我可以注入messagingService,我需要在我的服务层而不是User对象上执行此操作.

从“多UI”的角度来看,这是有道理的,因为执行操作的逻辑是从我的UI层(MVC)中取出的,并放入这些服务中…但我实际上只是将逻辑分解为另一个类而不是直接在控制器中执行它,如果我不会涉及任何其他UI,那么我刚刚交换了一个“胖控制器”用于“胖服务”,因为该服务实际上将封装每个控制器动作的方法来完成它的工作.

解决方法

DDD没有Active Record倾斜.删除不是应该在DDD中的实体(如用户)上的方法.

NHibernate确实很好地支持DDD方法,因为它与实体类完全脱离.

when that action needs to do something
like sending an e-mail,or touching
other non-related objects

您似乎缺少的一个难题是域事件.域实体不应直接发送电子邮件.它应该在域中引发一个重大事件发生的事件.实现一个类,其目的是在事件发生时发送电子邮件,并注册它以侦听域事件.

or,for instance,checking to see if
there are any users that have the same
e-mail before approving

在提交“批准”调用之前,可能应该检查这一点,而不是在批准的函数中.将决策推高到调用代码的水平.

So the next most logical way to do it,
I would think,would be to essentially
have a service per controller

这可以工作,如果它是在了解服务是客户端的入口点的情况下完成的.此处服务的目的是从前端/客户端接收DTO中的参数,并将其转换为针对实体的方法调用,以便执行所需的功能.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读