asp.net MVC ddd DRY vs松散耦合和持久性/数据访问层

Mas*_*low 1 asp.net-mvc domain-driven-design data-access-layer dry

因此,我理解它具有良好的松散耦合,我应该能够在应用程序根目录中使用几行代码替换我的DAL.

我有2个DAL编写,Linq-to-sql和一个JSon文件存储库(用于测试,因为我想试用System.Web.Scripting.JavascriptSerializer).

linq to sql将创建实体而不是我的商业模式.并通过在应用程序根目录中使用构造函数注入的IRepository向上提供它们.

我的JSon层没有任何自动生成的类可以反序列化,所以我迷失了一个简单的方法,让它依赖于接口或抽象类,仍然是函数.

这个问题基于以下假设/理解:

  • 我相信我需要linq到sql层来实现一个接口,所以编译时的应用程序域可以指示实体类将有一个位置来读/写所有当前模型的字段
  • 任何业务逻辑都要求在模型层中具有几乎相同名称和相同属性的另一组类
    • 然后需要采用DAL对象并将它们转换为业务对象并返回的转换方法.(即使双方都在实现相同的界面,这似乎效率很低)
      • 如果模型类或接口发生更改(接口,业务类,视图,dal实体),此代码是另一个必须进行更改的地方
  • 任何替代DAL的反序列化都要求我在该层中创建具有相同属性和字段的"实体"(更多重复)

因此,为了满足所有灵活性/敏捷性目标,我需要为每个应用程序域/业务对象提供一个接口,一个业务逻辑可以存在的具体类,以及实现该接口的DAL对象(这意味着不自动生成实体的层)必须是手工编码纯复制).

如何在没有大量重复和DRY损失的情况下使用松耦合?

Mar*_*ann 5

欢迎来到松散耦合代码的美丽和令人兴奋的世界:)

您正确理解了这个问题,但让我首先重申您已经暗示的内容:域模型(即所有域类)必须独立于任何特定的数据访问技术进行定义,因此您不能使用自动生成的LINQ来SQL(L2S)类作为您的Domain类的基础,原因很简单,您无法将这些类与其他技术一起重用(正如您在基于JSON的存储库中发现的那样).

每个Domain对象的接口甚至都无法帮助您,因为要避免使用Anemic Domain Models,您需要在Domain类中实现行为(并且您不能将行为放入接口中).

这意味着要对Domain对象进行水合和脱水,您必须拥有一些映射代码.它一直是这样的:在过去我们必须从IDataReader实例映射到Domain类,而现在我们需要从Data(L2S)类映射到Domain类.

我们希望有更好的东西吗?是.我们能得到更好的东西吗?大概.实体框架的下一个版本将支持持久性无知,正是出于这个原因:您应该能够将域模型定义为POCO,如果您提供地图和数据库模式,EF将负责其余部分.

在此之前,微软没有任何提供这种功能的东西,但NHibernate确实如此(需要注意的是:我对NHibernate没有经验,但很多聪明的人都说这是真的,我相信他们就是这样).这是很多人喜欢NHibernate而不是EF的主要原因.

松散的耦合需要大量的映射,所以我只能提出使用AutoMapper进行这种繁琐的工作的第二个女王的建议.

作为结束语,我想指出一个相关问题:映射并不一定意味着违反DRY.最好的例子是对应于给定Domain对象的强类型ViewModel.不要被语义相似性所迷惑.它们可能具有或多或少具有相同值的相同属性,但它们的职责差别很大.随着应用程序的增长,您可能会遇到一点点差异在这里和那里潜行,并且您会很高兴您将关注点分开 - 即使它最初看起来像是一些重复的工作.

在任何情况下:松散耦合在一开始就是更多的工作,但它将使您能够继续发展一个紧密耦合的应用程序在维护地狱之前很久就会冻结的应用程序.你是长期的,但即时的满足并非如此.