在针对以下类型的体系结构设置IoC容器时,我有一个简单的挂断。
在我的应用程序中,我有这样的层(从下到上):
当请求MicroServices层中的控制器(GET,POST等)时,SimpleInjector使用属性注入将ILogger的实例添加到BaseController。因此,MicroServices项目中的任何控制器都可以访问它。到目前为止效果很好。
这是我的问题:
我希望即使在域层中也可以访问整个体系结构的日志记录,而不会破坏任何交叉规则并使事物分离。我的想法可能是从Logging层可以订阅的域层发布的事件。但是,我离题了。我不明白的是如何使SimpleInjector将Logger实例传递给域(如果我应该,想法?)它是在app启动时发生的,还是仅在Web请求上发生?它应该是单例实例还是瞬态实例?如何才能最好地适应Log4Net(可能我的架构过于复杂或不足之处)。
我意识到注册是在启动时发生的,但是如何获取实例呢?根据我的理解,我应该使用自动构造函数注入而不是使用Container.GetInstance()来获取实例,但是尽管我阅读了大量内容,但我仍然无法弄清楚它是如何在Web API请求和SimpleInjector&之外工作的。 #39; Web API Extensions。
另外,有点无关。我正在抽象出Log4Net功能,但我最近了解到我可能不应该这样做。如果考虑到这一点,我会喜欢一些关于这一切如何联系在一起的建议。
答案 0 :(得分:4)
你的帖子有点含糊不清,而且没有更多的背景,这些问题很难回答,但我会尽我所能。
我甚至可以让整个架构都可以访问日志 在域层
如果您有明确的日志记录抽象,您可以将该抽象提供给应用程序并在整个应用程序中进行日志记录。
我正在抽象出Log4Net功能,但我最近学到了 我可能不应该这样做。
我不同意。我想你应该。如果可能,防止使应用程序的核心依赖于第三方组件,并且通过日志记录,这非常容易。符合define an abstraction原则的SOLID很容易。并且不要忘记,根据Dependency Inversion Principle,抽象应该是defined by the client。日志框架无法定义您需要的抽象。
但请确保不要像解释here那样陷入过多记录的陷阱。在大多数情况下,您不应该经常记录,而是快速失败,并且有一些通用的代码片段可以为您执行日志记录,而不是在整个代码库中调用您的ILogger.Log
。
如果您要发布事件,我认为这会大大降低您需要记录的时间,因为事件是完美的日志记录系统。只需将这些事件附加到表或磁盘上,您就会知道究竟在哪个时刻发生了什么。可能没有理由在日志中写入更多信息。
我不明白的是如何使SimpleInjector通过Logger 实例到域(如果我应该,想法?)
对此有很多意见。我和Mark Seemann赞成anemic domain models with commands and events on top(或者我可以说我的命令和事件会成为我的域模型吗?)。其他人在他们的域对象中有更多的业务逻辑。这些对象需要一些服务,例如ILoanCalculator
,你可能想要依赖注入,因为让那些域对象通过服务位置请求服务是very bad idea。
但不要忘记,不仅仅是构造函数注入。对于域对象,您可以使用方法注入,其中某些域方法需要的服务作为方法参数公开:
public class Loan
{
public void PayLoan(LoanPeriod periodToPay, ILoanCalculator calculator)
{
// ...
}
}
由于您将拥有调用这些域方法的服务类(我可以说command handlers吗?),您可以对这些服务类应用构造函数注入,并将依赖项传递给域方法。
我意识到注册是在启动时发生的,但是获取是怎么回事 实例
在每个请求开始时检索实例(构建对象图)。
据我所知,我应该使用自动构造函数注入 而不是使用Container.GetInstance()来获取实例
这是正确的。尽可能在从容器中解析的任何服务上使用构造函数注入。
但是尽管我阅读了很多,但我仍然无法弄明白 它在Web API请求和SimpleInjector的Web API之外工作 扩展。
我不确定我是否理解这一点。几乎所有应用程序都是基于请求的,无论是Web应用程序,Windows服务还是命令行工具。使用Web应用程序,请求作为Web请求从Internet进入。使用Windows服务,您有一个定时关闭的计时器,每个脉冲都可以看作是一个新请求(或者您可能正在使用SqlDependency,在这种情况下,引发的事件是新请求的开始)。控制台应用程序可能只有一个请求,然后很快就会死掉。对于Web应用程序,Simple Injector将隐式控制某些服务的生命周期,而Windows服务和后台进程则必须明确控制它。使用Simple Injector,LifetimeScope和ExecutionContextScope生活方式允许您定义一个显式范围,该范围控制此类请求的对象的生命周期。 WebApiRequestLifestyle
实际上在后台使用ExecutionContextScopeLifestyle
,并根据Web API请求开始和结束范围。