存储库、管道、业务逻辑和域模型 - 如何将这些组合在一起

本文关键字:组合 在一起 模型 管道 业务 逻辑和 存储 | 更新日期: 2023-09-27 17:56:59

我正在设计N层应用程序,我遇到了一个困难,你可能有一个解决方案。表示层是MVC。

我的ORM是使用LinqToSQL执行的 - 它是一个单独的项目,为存储库提供服务。

每个存储库都有一个接口和至少 1 个具体实现。

存储库具有以下方法: FindAll(), Save(T entity), Delete(int id)

FindAll()返回某种类型的 IQueryable,这意味着它返回我可以应用过滤器的查询。

ORM映射是使用数据库优先方法执行的,其中首先创建表,然后由SQL Metal生成类。

我添加了一个与存储库一起使用的管道层。它将进一步的筛选器应用于查询。例如 OrderRepository.FindAll().Where(o => o.CustomerId == 10)

管道还返回某种类型的IQueryable,这意味着我可以将其进一步传递到层并用它做更多的事情。

此时,我想移动到 BusinessLogic 层,但我不想再使用实体模型,我想将实体模型转换为域模型。这意味着我可以向模型添加验证,并在表示层中使用该模型。模型不能在MVC项目中定义,因为它依赖于表示层,所以这是一个不。

我相当确定业务逻辑(行为)和模型必须与管道、数据和表示层分开存储。问题是在哪里?

例如,管道有三种方法:1. 按客户查找 ID2. 查找顺序 ID3. 通过其他东西找到

所有这些方法都返回 IQueryable 的顺序。我需要将其转换为域模型,但我不想为每个方法执行此操作,因为它不可维护。

我觉得这个模型相当健壮和可扩展。我只是看不出从实体映射到域模型的最佳位置是什么,反之亦然。

谢谢

存储库、管道、业务逻辑和域模型 - 如何将这些组合在一起

首先,如果在此处应用域驱动设计原则,则应用程序中不得包含 BusinessLogic 层。所有业务逻辑都应位于域模型中。

但是使用 LinqToSQL 很难实现,因为它不支持继承映射,并且您必须处理分部类才能将业务逻辑放入您的域中。因此,我强烈建议考虑从LinqToSQL迁移到NHibernate或Entity Framework Code First。在这种情况下,也不必将持久性模型转换为域模型,反之亦然。

如果您仍然想进行转换,可以查看自动映射器

从领域驱动的角度来看,您需要一个工厂来将"数据库实体"转换为域模型实体。

当您考虑在管道末尾将"数据库实体"转换为域模型实体时,您应该意识到,在转换为域模型实体(投影)后,您将无法使用 IQueryable 功能,因为投影将触发表达式树的执行。例如,如果您为客户数据库实体调用 FindAll,然后将 IQueryable 转换为(或投影到)它将执行的客户域实体(请求整个表的内容)。

这就是我做N层项目的方式。此体系结构具有很大的关注点分离。听起来你已经在朝着这个方向前进了。

在 Mvc 项目中是所有常用对象(控制器、视图模型、视图、帮助程序等)。相当直截了当。所有视图都是强类型的。加上我修改的 T4 模板,用于生成控制器、视图和视图模型。

在业务模型项目中,我拥有所有业务对象和规则,其中包括定义数据存储库功能的接口。与其为每个业务对象/表提供一个存储库,我更喜欢按功能对我的存储库进行分组。与博客相关的所有对象都位于一个存储库中,而与照片库相关的所有对象都位于单独的存储库中,日志记录可能位于第三个存储库中。

您可以在此处放置管线层。

在数据项目中,我实现了这些数据存储库接口。您可以使用 Linq2SQL,而不必使用分部类。扩展这些 Linq2SQL 分部类意味着您已将 ORM 绑定到域模型。你真的不想做的事情。您希望将这些生成的数据类保留在数据域中。下面是一个返回业务模型对象的 Linq2SQL 选择示例。

from t in Table
where t.Field == keyField
select new BusinessModel.DataObject
{
  Id = t.Id,
  Field1 = t.Field1,
  Field2 = t.Field2
}

如果我是你,我会使用 CodeFirst 方法或使用 NHibernate 查看 EntityFramework 4.1。其中任何一个都会将数据模型映射到域模型。然后,若要将域模型映射到视图模型,可以使用 AutoMapper,或者编写自定义代码或编写将生成映射代码的 T4 模板。

您可以将 dbml 文件生成的代码作为业务对象的起点。

除了Xelibrion的评论之外,您还可以查看LightSpeed以满足您的ORM需求。您目前正在使用LinqToSQL,因此您应该发现Lightspeed非常简单,因为它使用了相同的想法。

http://www.mindscapehq.com/products/lightspeed

如果你能让你的数据映射模型,与你的更高级别想要的形式更匹配,那么希望你可以简化事情。系统中的复杂性越低,错误的范围就越小。

所有这些方法返回的 IQueryable 次序。我需要将其转换为 域模型,但我不想做 它每个方法,因为它不会 可维护。

这不是一个真正的评估,可能会阻止您看到正确的解决方案。