【问题标题】:Help w/ DDD, SOA and PI帮助/DDD、SPA 和 PI
【发布时间】:2011-07-20 18:59:23
【问题描述】:

在不涉及所有血腥细节的情况下,我正在尝试设计一个将由多个客户端应用程序使用的基于服务的解决方案。该解决方案允许管理员创建和修改常规用户用于执行数据输入的文档模板。我的目的是使该应用程序成为最佳实践、技术等的学习工具。

同时,我必须适应精神分裂的环境,因为“当权者”永远无法坚持他们关于技术和工具的决定。例如,我今天使用的是 Linq-to-SQL,因为他们还没有准备好转到 EF4,但也有关于切换到 NHibernate 的讨论。因此,我必须使代码尽可能持久无知,以尽量减少更改 OR/M 工具所需的工作。

此时,我也仅限于使用部分类方法来扩展 Linq-to-SQL 类,以便它们实现在我的业务层中定义的接口。我不能使用 POCO,因为管理层坚持要求我们利用所有内置工具等,所以我必须支持 Linq-to-SQL 设计器。

也就是说,我的服务接口有一个 StartSession 方法,该方法在其签名中接受模板标识符。操作流程如下:

  1. 如果当前用户和指定模板的数据库中已存在会话,请更新记录以显示当前活动。如果没有,请创建一个新的会话对象。
     
  2. 会话与模板的一个实例相关联,称之为“表单”。因此,如果会话是新的,我需要检索模板信息来创建新的“表单”,将其与会话相关联,然后将会话保存到数据库中。另一方面,如果会话已经存在,那么我还需要使用用户输入并存储在会话中的数据加载“表单”。
     
  3. 最后,会话(包含表单定义和数据)返回给调用者。
     

我的第一个目标是在我的应用程序的逻辑层之间创建清晰的分离。二是保持执着无明(如上所述)。第三,我必须能够测试所有内容,因此必须将所有依赖项外部化以便于模拟。我正在使用 Unity 作为 IoC 工具来在这方面提供帮助。

为了实现这一点,我根据需要定义了我的服务类和数据协定以支持服务接口。服务类将具有从实际执行工作的业务层注入的依赖项。这就是让我感到混乱的地方。

我一直在尝试使用工作单元和存储库路线来帮助解决持久性无知问题。我有一个 ITemplateRepository 和一个 ISessionRepository ,我可以从我的 IUnitOfWork 实现中访问它们。服务类获得了我的 SessionManager 类(在我的 BLL 中)注入的实例。 SessionManager 通过构造函数注入接收 IUnitOfWork 实现并将所有持久性委托给 UoW,但我发现自己在玩各种逻辑的 shell 游戏。

上面描述的所有逻辑都应该在 SessionManager 类中还是在 UoW 实现中?我希望存储库实现中的逻辑尽可能少,因为更改数据访问平台可能会导致对应用程序逻辑进行不必要的更改。由于我的存储库正在针对一个接口工作,我如何最好地创建新会话(请记住,有效的会话具有对模板的引用,呃,正在使用的表单)?即使我必须支持设计人员并在存储库实现中使用 AutoMapper 之类的工具来处理对象的翻译,仍然使用 POCO 会更好吗?

啊!

我知道我只是陷入了分析瘫痪,所以我可能只需要一点推动。理想的情况是,如果有人可以提供一个示例,在给定我定义的业务规则和架构约束的情况下,您将如何解决问题。

【问题讨论】:

  • 我自己意识到的一件事是我的“SessionManager”类是我的工作单元。所以,我去掉了第二类和抽象层。其余部分仍在工作。

标签: domain-driven-design repository soa unit-of-work persistence-ignorance


【解决方案1】:

如果您不使用 POCO,那么您就不会真正成为数据存储不可知论者。使用 POCO 可以让您的系统启动并运行基于内存的存储库,无论如何这都是您可能希望用于单元测试的。

AutoMapper 听起来不错,但我不认为它会破坏交易。除非您有数百个表,否则将 POCO 映射到 EF4、LinqToSql、nHibernate 并不是那么耗时。当/如果您的 POCO 开始偏离您的持久层,那么您可能会发现 AutoMapper 并不真正符合要求。

【讨论】:

  • 使用部分类方法,Linq-to-sql 类在我的业务逻辑和服务代码中看起来就像是 POCO。另一方面,AutoMapper 为相同的接口创建一个代理对象,然后由相同的业务逻辑使用。业务逻辑和服务代码都不知道除了这些接口之外的任何东西。没有任何数据访问代码确实使它持久无知。
  • 只是为了更新我最终得到这个的地方 - 我发现我在整个 DDD 事情上都偏离了目标,并且已经使用了一个真正的 POCO 解决方案,其中我的域对象不仅提供状态,而且适当的业务逻辑也是如此。服务外观层委托给应用程序服务,该服务使用存储库类来协调域对象。由于我的域对象和 L2S 实体之间的阻抗不匹配,存储库还负责层之间的映射。我对那部分不满意,但在我们获得支持真实映射的 ORM 之前,它必须这样做。
猜你喜欢
  • 2010-10-25
  • 2021-02-06
  • 1970-01-01
  • 1970-01-01
  • 2017-11-14
  • 2011-11-18
  • 1970-01-01
  • 2011-06-14
  • 2011-06-03
相关资源
最近更新 更多