代码之家  ›  专栏  ›  技术社区  ›  Maslow

ASP.NET MVC DDD干耦合与松耦合及持久性/数据访问层

  •  1
  • Maslow  · 技术社区  · 15 年前

    因此,根据我对它的理解,通过良好的松耦合,我应该能够用应用程序根目录下的几行代码交换出DAL。

    我写了2个DAL,linq-to-sql和一个JSON文件存储库(用于测试,因为我想试用system.web.scripting.javascriptserializer)。

    Linq to SQL将创建实体,而不是我的业务模型。并通过在应用程序根目录使用构造函数注入的IRepository向上提供它们。

    我的JSON层没有任何要从中反序列化的自动生成类,所以我丢失了一种简单的方法,让它依赖于接口或抽象类和静态函数。

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

    • 我相信我需要linq-to-sql层来实现一个接口,这样应用程序域在编译时就可以指示实体类将有一个地方来读/写所有当前模型的字段。
    • 任何业务逻辑都要求在模型层中具有几乎相同的名称和属性的另一组类
      • 然后需要转换方法来获取DALS对象并将其转换为业务对象并返回。(即使双方都在实现相同的接口,这似乎效率非常低)
        • 如果模型类或接口发生更改(接口、业务类、视图、DAL实体),则此代码是另一个必须进行更改的地方。
    • 任何可选DAL的反序列化要求我创建具有该层中相同属性和字段的“实体”(更多重复)

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

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

    2 回复  |  直到 10 年前
        1
  •  2
  •   queen3    15 年前

    不是我正确理解问题,而是为了解决重复的类,您可以使用 AutoMapper .

    请注意,您可以声明性地应用映射或使用反射,即半自动应用映射。例如参见 here -这与数据层无关,但显示了简单属性如何有助于自动映射。在这种情况下,MVC应用属性,但您可以发明自己的引擎来查找[实体(“订单”)]属性并应用automaper。

    而且,你不能只使用“几行”就拥有100%的持久性独立性。ORM选择在这里起着重要作用。例如,linq-to-sql不能使用普通类(poco),因此重新使用它们不像使用nhibernate那样容易。使用存储库,您将在数据层中有许多查询;不同的ORM通常具有不同的查询语法或实现(甚至LINQ并不总是在ORM之间兼容),因此切换数据访问可能是完全替换数据层的问题,这不是几行(除非您的应用程序是“hello,world!”).

    上面的automaper解决方案实际上是一种自焙的形式。所以您可能需要考虑一个更好的ORM来满足您的需求?为什么不使用EF4,特别是考虑到它现在支持POCO,并且与LINQ to SQL非常相似,至少在查询语言中如此?

        2
  •  5
  •   BenMorel Manish Pradhan    10 年前

    欢迎来到松散耦合代码的美丽而激动人心的世界:)

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

    每个域对象的接口甚至都不会帮助您,因为为了避免贫乏的域模型,您需要在域类中实现行为(并且您不能将行为放入接口中)。

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

    我们能要更好的吗?对。我们能得到更好的东西吗?可能。实体框架的下一个版本将支持对持久性的忽略,原因正是这样的:您应该能够将域模型定义为POCO,如果您提供了一个映射和一个数据库模式,那么EF将负责其余的部分。

    在那之前,微软没有提供这种功能的任何东西,但是NHibernate有(注意:我没有NHibernate的经验,但是很多聪明人说这是真的,我相信他们)。这是很多人比英孚更喜欢NHiberiate的一个主要原因。

    松耦合需要大量的映射,所以我只能附和queen3的建议,在这种繁琐的工作中使用automapper。

    最后,我想指出一个相关的问题:映射并不一定意味着违反dry。最好的例子是当涉及到对应于给定域对象的强类型视图模型时。不要被语义相似性愚弄。他们可能或多或少地拥有相同的财产和相同的价值,但他们的责任相差很大。随着应用程序的增长,您可能会体验到这里和那里潜藏的细微分歧,并且您会很高兴您的关注分离-即使它最初看起来像很多重复的工作。

    在任何情况下:松耦合在开始时都要做更多的工作,但它将使您能够继续开发一个应用程序,在这个应用程序中,紧密耦合的应用程序很早以前就会冻结在维护地狱中。你要做的是长期的工作,但那不是即时的满足。