4

我对 BLL 和 DAL 的关系有点困惑。BLL 是否应该通过依赖注入封装 DAL?或者 BLL 是否应该只作用于域对象和 DAL 分别保存/更新?

例如,想象(在典型的 MVC 应用程序中)一个取消订单功能,要求您更新订单并更新库存。以下是我的行动的样子吗?

public ActionResult CancelOrder (Guid orderId) {
    Order order = orderRepository.Get(orderId);
    StockItem stockItem = stockRepository.Get(order.StockItemId);

    _orderService.CancelOrder(order, stockItem);
    orderRepository.Update(order);
    orderRepository.Update(stock);
    Return View();
}

还是应该更像以下?

public ActionResult CancelOrder (Guid orderId) {
    _orderService.CancelOrder(orderId);
    Return View();
}

(within OrderService)
public void CancelOrder(Guid orderId) {
    Order order = orderRepository.Get(orderId);
    StockItem stockItem = stockRepository.Get(order.StockItemId);

    order.Cancelled = true;
    stockItem.AmountInStock = stockItem.AmountInStock + order.Amount;
    orderRepository.Update(order);
    orderRepository.Update(stock);
}

使用此选项,所有内容都将由 BLL 处理,包括数据访问。将注入存储库以避免紧密耦合。然后,任何实体检索都将采用与_orderService.GetOrder(orderId);直接进入存储库不同的形式。

请原谅这些例子的粗俗,因为我没有很多时间。我写的任何东西都有意义吗?还是我在荒野中?

4

4 回答 4

5

绝对不是第一个选项,它将您的业务逻辑嵌入到控制器中。问题不在于控制器本身访问数据对象,而在于必须遵循由业务规则规定的程序。此过程在控制器中没有位置。

因此,您应该选择第二个选项,或者可能制作Cancel一个Order. 如果您已经编写过类似的代码,请保持一致性。

于 2012-09-05T10:08:14.977 回答
1

考虑关注点分离,Controller 来自 MVC 模式,即 PRESENTATION 模式,因此控制器应该包含支持表示层的表示逻辑,而不是业务逻辑。

一致认为业务逻辑应该在域实体中,但也有一些 APPLICATION 逻辑充当存储库之间的协调者,这就是为什么服务层在路上被淘汰的原因。

因此,选项 2 应该是你的方式。

于 2012-09-05T10:19:19.200 回答
1

你真的在这里问了两个问题:

控制器与业务层应该是什么?

=> 我倾向于认为您的第一个片段中的代码是应用程序层服务的正确责任级别(如果您承认可以将两者相提并论,那么对于控制器来说,这有很多关于这些时间的讨论)。从存储库中获取Order并在取消操作后保存它看起来不像是纯粹的业务逻辑。它更多地与周围的事务/工作单元和用例的管道有关。

我只想更改一件事 - 尝试一次将更改保存到受您的交易影响的所有实体。如果您必须手动更新可能在操作结束时更改的每个实体,这将是一个很大的痛苦,并且会不必要地污染控制器。创建一个工作单元系统(或使用现有的实现),它将一次保留所有更改并删除存储库中的所有 Update() 方法。

除此之外,正如 Jon 所建议的那样,我还相信Order包含该方法的富域对象Cancel()比服务更可取 - 但这是另一个争论。

BLL 和 DAL 之间应该有什么样的关系?

=> BLL 不应该与 DAL 紧密耦合,并且作为最中心的层,它不应该直接引用外层。这样,您可以轻松地在另一个应用程序、另一个 DAL 等中重用您的 BLL。

但是,有时某些业务对象需要直接访问它们还没有引用的其他对象,这基本上意味着从数据库中获取它们。换句话说,BLL 中的某些操作需要与存储库通信。因此,我总是将存储库接口放在 BLL 中,但它们的实现驻留在 DAL 中,并在运行时注入到 BLL 中。

因此,BLL 只是松散地耦合到 DAL。它仍然对持久性一无所知,因为它只操纵看起来像中性对象集合的外观(存储库),并且不知道数据是如何存储、水合等的。

于 2012-09-05T13:49:30.953 回答
0

BLL 应该作用于您为应用程序创建的业务对象。理想情况下,它不应该知道数据库和相关操作。如果您希望保持松散耦合,请使用依赖注入从 DAL 调用方法。

于 2012-09-05T10:07:30.897 回答