我使用Autofac与ASP.NET MVC集成,我的所有控制器都接收依赖项,Autofac自动解析嵌套依赖项。伟大的工作
但是如何解决控制器实例化范围之外的依赖?在我的代码深处的某些地方,我需要向解析器询问我的Logger。一方面,将Logger作为依赖项传递给我创建的每个小对象似乎是错误的,而另一方面,依赖于我的代码中如此深的依赖性解析器似乎是错误的
例如,我有一个名为Result的类,它从许多动作返回。它是一个一致的使用对象,我的应用程序代码可以依赖从更深层回来。当更深层次的代码向此对象添加UI错误时,我想自动将其添加到需要解析的记录器中。每个班级都依赖于记录器会妨碍
任何帮助表示感谢
答案 0 :(得分:37)
您正在寻找的是MVC的DependencyResolver.Current
:
var logger = DependencyResolver.Current.GetService<ILogger>();
答案 1 :(得分:7)
你可以使用事件(发布/子方法),如果每个对象的依赖都会激怒你,但我不认为对中央Logger解析器的依赖有任何问题。 如果你真的需要从每个类登录,那么你肯定可以将日志记录作为应用程序的核心方面,并且你在心理上将其作为其他常见的库类型,如String或Ints,它们无处不在,可以安全依赖。 但我会建议你别的东西。恕我直言,你应该建立架构,不要登录每个班级。如果您的日志记录仅仅(或大部分)是关于编写错误(例外),那么不要使用它来对您的域模型进行策略。让我们把它放在服务层insteád。这种编排层可以正确地评估每个捕获的异常并仅记录必要的内容。让我们将这些异常冒充到堆栈跟踪中较低的可能位置并将其作为最后一个处理它们。
答案 2 :(得分:3)
使用DependencyResolver.Current绝对是一种解决ASP .NET MVC问题的方法,因为它是一个框架功能。但是,我会首先尝试遵循"Best Practices" section of the Autofac Wiki
中的以下建议“使组件可以访问容器,将其存储在公共静态属性中,或者在全局”IoC“类上使用Resolve()这样的函数会破坏使用依赖注入的目的。这样的设计有更多与服务定位器模式相同。 如果组件依赖于容器,请查看它们如何使用容器来检索服务,并将这些服务添加到组件(依赖注入)构造函数参数中。 对需要实例化其他组件或以更高级方式与容器交互的组件使用关系类型。“
如果不能按上面的建议重新设置依赖关系,我会使用DependencyResolver。
答案 3 :(得分:0)
寻找这个问题的另一个解决方案的人可能会看一下利用Autofac直接注入的IComponentContext
解析器服务的其他SO answer。