在设置ioc容器时,我有一个简单的挂断,关于以下类型的体系结构。

在我的应用程序中,我有这样的图层(从下到上):

  • 工程。域名
  • 工程。网页 (系统。网络。Http等。加一些核心的HTTP类型逻辑)
    • 在这个项目中有一个 基本控制器
  • 工程。微型服务 实现GET/POST等。在Web API2.2中。这些继承自Project中的BaseController。Web和参考项目。域名
  • 工程。日志记录 这是我横切伐木的尝试

当微服务层中的控制器被请求时(GET,POST等)。)SimpleInjector使用属性注入将ILogger的实例添加到BaseController。因此,微服务项目中的任何控制器都可以访问它。到目前为止,这很有效。

这是我的问题:

我想使整个架构(即使在域层)都可以访问日志记录,而不会破坏任何交叉规则并保持分离。我的想法可能是从日志记录层可以订阅的域层发布的事件。但是,我离题了。我不明白的是如何让SimpleInjector将记录器实例传递给域(如果我应该,想法?)它发生在应用程序启动时,还是只发生在web请求上?它应该是一个单例实例,还是瞬态?这将如何最适合Log4Net(这可能是我过度或不足复杂的架构)。

我意识到注册发生在启动时,但是获取实例呢?据我了解,我应该使用自动构造函数注入,而不是使用容器。GetInstance()获取实例,但尽管我广泛阅读,但我仍然无法弄清楚它是如何在Web API请求和SimpleInjector的Web API扩展之外工作的。

还有,有点不相关。我正在抽象出Log4Net功能,但我最近了解到我可能不应该。我会喜欢一些关于这一切如何联系在一起的建议,考虑到这一点。

有帮助吗?

解决方案

你的帖子有点模糊,充满了没有更多上下文就不容易回答的问题,但我会尽我所能。

我想使整个架构都可以访问日志记录,甚至 域层中

如果您有明确的日志记录抽象,则可以使该应用程序可用该抽象,并在整个应用程序中执行日志记录。

我正在抽象出Log4Net功能,但我最近了解到 我可能不应该。

我不同意。我想你应该。如果可能的话,防止使应用程序的核心依赖于第三方组件,并且通过日志记录,这真的很容易做到。这很容易 定义抽象 这符合 固体 原则。别忘了,根据 依赖反转原理, ,抽象应该是 由客户端定义.日志框架无法定义您需要的抽象。

但请务必不要像解释的那样陷入太多日志记录的陷阱 这里.在大多数情况下,你不应该经常记录,而是快速失败,并且有一些通用的代码为你做日志记录,而不是调用你的 ILogger.Log 遍布整个代码库。

如果您正在发布事件,我认为这大大降低了您需要记录的时间,因为事件是完美的日志记录系统。只需将这些事件附加到表或磁盘上,您就知道在哪个时刻发生了什么。可能没有理由将更多信息写入日志。

我不明白的是如何让SimpleInjector通过记录器 实例到域(如果我应该,想法?)

对此有很多意见。我和 马克*塞曼 恩惠 顶部有命令和事件的贫血域模型 (或者我被允许说我的命令和事件成为我的领域模型?).其他人在他们的领域对象中有更多的业务逻辑。这些对象需要一些服务,例如 ILoanCalculator, ,并且您可能想要依赖注入,因为让这些域对象通过服务位置请求服务是一个 非常糟糕的主意.

但是不要忘记,除了构造函数注入之外,还有更多的东西。对于您的域对象,您可以使用方法注入,其中某些域方法需要的服务作为方法参数公开:

public class Loan
{
    public void PayLoan(LoanPeriod periodToPay, ILoanCalculator calculator)
    {
        // ...
    }
}

既然你会有服务类(我可以说吗 命令处理程序?)调用这些域方法,您可以在这些服务类上应用构造函数注入,并将依赖关系传递给域方法。

我意识到注册发生在启动时,但如何获得 实例?

在每个请求开始时检索实例(构建对象图)。

据我了解,我应该使用自动构造函数注入 而不是使用容器。GetInstance()获取实例

这是正确的。在从容器解析的任何服务上尽可能使用构造函数注入。

但是,尽管我广泛阅读,我仍然无法弄清楚如何 这在Web API请求和SimpleInjector的Web API之外工作 扩展。

我不确定我是否理解这一点。几乎任何应用程序都是基于请求的,无论这是web应用程序,windows服务还是命令行工具。使用web应用程序,请求作为web请求来自internet。对于windows服务,您有一个定时器定期关闭,每个脉冲都可以被视为一个新请求(或者您可能正在使用SqlDependency,在这种情况下,引发的事件是新请求的开始)。控制台应用程序可能只有一个请求,然后不久就死了。对于web应用程序,Simple Injector将隐式控制某些服务的生存期,而windows服务和后台进程则必须显式控制这一点。用简单的注射器 生命镜,生命镜执行;执行 lifestyles允许您定义一个显式范围,用于控制此类请求的对象的生存期。该 WebApiRequestLifestyle 事实上,使用 ExecutionContextScopeLifestyle 在后台,开始和结束每个Web API请求的范围。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top