【问题标题】:Logging crosscutting concern needs access to data layer记录横切关注点需要访问数据层
【发布时间】:2015-01-13 14:12:33
【问题描述】:

假设我有一个类似于Layered Architecture Sample 的架构。我们还假设每个大盒子都是它自己的项目。框架框和每一层将是它自己的项目。如果我们不使用 IoC 而是采用没有接口的传统分层方法,Service 会引用 Business,而 Business 会引用 Data,而所有这些都会引用 Framework。

现在的要求是对数据库进行日志记录,因此框架可能需要引用服务来访问数据。这有两个问题:

  1. 你现在有一个循环依赖(记住,没有接口)。如果您使用带有 IoC(依赖注入或服务定位器)和组合根的接口,大部分问题都可以解决。这是唯一的方法吗?还是您可以在没有界面的情况下以某种方式做到这一点?
  2. 如果您从事业务并需要记录某些内容,则必须再次跳转到服务。有没有办法只从 Presentation 而不是从没有组合根的 Service/Business/Data 跳转?

我知道我在某种程度上回答了我自己的问题,但我基本上想了解这种架构在没有 IoC 的情况下是否可行。

【问题讨论】:

    标签: language-agnostic circular-dependency n-tier-architecture


    【解决方案1】:

    如果没有一些控制反转,您将无能为力。

    假设您的语言支持 .NET 中的反射之类的功能,您可以尝试动态调用代码并在运行时反转控件。您不需要接口,但您可能需要标记/装饰或对上层所需的类型进行约定。

    我现在只是在想一些疯狂的、不实用的方法:您可以对二进制文件进行后处理并在每一层中注入日志记录代码。

    【讨论】:

    • 反射和所有超出我想要的东西,但感谢您的确认。即使使用 IoC,您也无法真正进行循环依赖注入,除非您正在处理单例(至少在 Autofac 中),但至少您可以选择。
    【解决方案2】:

    对于这个例子,我会在需要记录的业务层调用记录方法。调用一个级别真的没有任何意义。那将是一个不必要的抽象,听起来你已经收集了很多。

    在从业务层进行日志记录时,服务层是否提供了任何抽象的日志记录?如果是这样,也许可以为业务层日志创建某种外观。不过,如果您不需要这种抽象,我会直接调用业务日志记录方法。

    【讨论】:

    • 直接调用业务日志方法的问题是需要循环引用。
    • 如果您从业务层调用业务日志记录方法,则不必担心依赖关系。图层不需要引用自身。如果您尝试引用服务层并从业务中调用那里的日志记录方法,您只会遇到循环依赖问题。
    • 我可能会在这里回答我自己的问题...服务层类似于 Web 服务,它本质上必须有一个接口(即使我说没有接口)才能跳转到另一个app 域,所以那里没有循环依赖。一个应用程序域中的循环依赖是业务 -> 数据 -> 横切(用于日志记录)-> 业务(用于记录到数据库),但这应该有效:业务 -> 数据 -> 横切 -> 服务 -> 业务,与需要注意的是,当我已经在服务中时,我正在跨网络 (localhost) 跳转以访问该服务。
    【解决方案3】:

    IMO,由于日志记录是横切关注点,它不应该引用您的数据层。在您的问题中,我看到您假设您正在登录数据库。即使这是您的要求,您也必须将数据库连接/日志记录代码插入与应用程序数据层分开。它将成为您的日志库的一部分,而不是数据层的一部分。不要将其视为数据层的一部分。正是这种视角,您可以继续开发/增强日志记录 [框架],并且它将与您的数据层分开。

    从我的角度来看,数据层仅构成应用程序数据访问而不是日志记录。具体你可以看看 NLog 或 Log4Net 库,看看它们是如何不关心应用程序的数据访问层策略的。

    希望这会有所帮助。

    【讨论】:

    • 您可能在这里有所收获。我认为我应该能够重用我自动生成的 DAO。让我们假设你是对的。我无法直接访问数据库日志的 Web 层如何?它不会通过业务层吗?或者我们可以从技术上说它不是“业务逻辑”,所以应该有一个单独的项目/服务作为“横切逻辑层”?通过将其分离出来,我认为依赖关系不会成为问题,除非横切代码失败并尝试记录,然后我们又回到了开始的地方。
    • @Nelson 请忽略上述内容。我无法直接访问数据库日志的 Web 层如何?日志记录决定取决于您的应用程序架构。从 Logging 的角度来看,这并不重要。将其视为为常规 n 层/3 层架构构建的可重用组件/框架/服务。在日志记录项目/服务中,您不会引用应用程序的业务逻辑/数据层。日志记录独立于任何应用层。如果“记录到数据库”失败,那么您可以记录到某个文本文件或更好地记录到指定机器的事件日志中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-05
    • 1970-01-01
    • 2011-08-01
    • 2020-02-19
    • 1970-01-01
    相关资源
    最近更新 更多