1

我已经开始研究将驻留在单个服务器(包括数据库)上的 WebForms(不是 MVC)应用程序,并决定使用(我认为)非常标准的 N 层架构来设计它。

数据层

  • 使用实体框架 4 和通用存储库/工作单元模式。
  • 将广泛使用存储过程(这是权力赋予我的要求)。
  • 持有对业务对象层的引用,以将数据传入/传出 BO。

业务对象“层”

  • 代码优先的 POCO。
  • 他们将拥有的唯一行为是验证内容(名称不为空,数量必须为正整数等)。
  • 不引用任何其他层或关心数据的来源。

业务逻辑层

  • 包含我的业务服务,它将充当 UI 和数据层之间的中间人,并执行其他业务“规则”,例如记录更改时的电子邮件通知等。
  • 具有对数据层和业务对象层的引用。
  • 将 BO 传入/传出 UI。

界面层

  • 包含所有常见的 UI 内容 - Web 表单、javascript、样式表等。
  • 引用业务逻辑和业务对象层。

几个问题......好吧,实际上很多:/

  1. 当应用程序要跨多个服务器,将使用 Web 服务,或者当传递给视图的数据是多种类型的业务对象的编译时,我可以看到使用 DTO 的优势,但是真的需要当所有东西都在同一台物理机器上时,将所有 BO 转换为 DTO,然后在 BLL 和 UI 之间传递它们?大多数 DTO 都是“复制、粘贴、将‘DTO’添加到类名末尾”的事情,所以这似乎是一种毫无意义的浪费时间?我最终得到的只是更高的维护成本和稍慢的性能(现在必须用相同的代码更新两个类而不是一个)。
  2. 假设在某些情况下需要 DTO,是否可以向 DTO 添加验证(即:名称不能为空,数量必须是正整数等)。?
  3. 使用 FluentValidation 之类的东西将验证代码分离到它自己的类库中是最好/更好的做法吗?如果我这样做了,那么 BO 基本上会变成 DTO,因为它们的行为为零……在这种情况下,我似乎最终会得到一个贫血的域模型?
  4. 当 BO 被 EF 使用时,数据层是否可以引用业务对象层?
  5. 看到我的服务“Find(predicate)”和“FindAll()”方法将使用相同的存储过程(提取所有记录),这是否意味着执行以下操作:

    List<Foo> myFoo = FooService.Find( f => f.Country == "Australia" && f.Status = OrderStatus.New );
    

实际上会通过存储过程提取所有记录,并在事后执行过滤吗?在这种情况下,如何使用只检索所需记录的存储过程,同时允许使用 linq 表达式(需要允许 &&、||、!= 等)?这甚至是可能的吗(无需放弃存储过程)?

4

1 回答 1

0

如果它是一个单一的应用程序,我认为它是一个过度架构。在 YAGNI 和 DRY 之后,只需让您的服务返回 BO。我还建议在使用 WebForms 时使用 MVP 模式,甚至避免使用“服务层”,而只使用域驱动设计 (DDD)。

http://en.wikipedia.org/wiki/Domain-driven_design

http://en.wikipedia.org/wiki/Don 't_repeat_yourself

http://en.wikipedia.org/wiki/You_ain 't_gonna_need_it

http://www.codeproject.com/Articles/23562/Building-an-MVP-Framework-for-NET-Part-1-The-Basic

MVP 真的很容易实现。解释总是充满组件和箭头,示例实现总是试图让事情变得复杂(我不知道为什么),但它确实是一种简单的关注点分离模式,它确实有效:)

希望能帮助到你 :)

于 2012-05-13T15:06:41.453 回答