ASP.NET MVC3 中对 autofac 依赖解析器的全局访问?
我将 Autofac 与 ASP.NET MVC 集成一起使用,我的所有控制器都接收依赖项,并且 Autofac 自动解析嵌套依赖项。很好
,但是我如何解决控制器实例化范围之外的依赖关系?在代码深处的某些地方,我需要向解析器询问我的记录器。一方面,将 Logger 作为依赖项传递给我创建的每个小对象似乎是错误的,另一方面,在我的代码中如此深入地依赖依赖解析器似乎是错误的,
例如,我有一个名为 Result 的类这是从许多操作中返回的。它是一个一致使用的对象,我的应用程序代码可以依赖它从更深的层返回。当更深层次的代码向该对象添加 UI 错误时,我想自动将其添加到记录器,这需要解决。让每个类都依赖于记录器只会妨碍
任何帮助,谢谢
I am using Autofac with ASP.NET MVC integration, all my controllers receive dependencies and Autofac resolves nested dependencies automatically. Great it works
But how can I resolve a dependency outside the scope of controller instantiation? In some places deep in my code I need to ask the resolver for my Logger. On the one hand it seems wrong to be passing the Logger as a dependency down to every little object I create, and on the other it seems to wrong to depend on dependency resolver so deep in my code
For example, I have a class called Result which is returned from many actions. It's a consistent used object that my application code can rely on coming back from the deeper layers. When the deeper layered code adds a UI error to this object I want to automatically add it to the logger, which needs resolving. Having every class take a dependency on logger would just get in the way
Any help appreciated thanks
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
您正在寻找的是 MVC 的
DependencyResolver.Current
:The thing you're looking for is MVC's
DependencyResolver.Current
:好吧,如果每个对象中的依赖关系激怒了您,您可以使用事件(发布/订阅方法),但我不认为对中央记录器解析器的依赖有任何问题。
如果您确实需要从每个类进行日志记录,那么您当然可以将日志记录作为应用程序的核心方面,并且您可以在心理上将其视为其他常见的库类型,例如无处不在且可以安全依赖的 String 或 Ints 。
但我会建议你一些别的东西。恕我直言,您应该重新设计架构,并且不要登录每个班级。如果您的日志记录仅(或主要)关于编写错误(异常),那么不要用它来污染您的域模型。让我们将其放置在服务层中。这种编排层可以正确评估每个捕获的异常并仅记录必要的异常。让我们将这些异常冒泡到堆栈跟踪中可能较低的位置,并将它们作为最后一件事进行处理。
Well you can use eventing (pub/sub approach) if dependency in every object irritates you but i dont thing there is anything wrong with dependency on central Logger resolver.
If you really need to log from every class then you cetrtainly can approach logging as very core aspect of your application and you mentally aproach it as other common library types like String or Ints which are ubiquitous and safe to depend on.
But i would suggest you something else. IMHO you should rething the architecture and dont log in every class. If your logging is only (or mostly) about writing the errors (exceptions) then dont polute your domain model with it. Lets place it in Service layer insteád. This kind of orchestrating layer can correctly evaluate each catched exception and log only what is neccesary. Let's bubble those exceptions to the lower possible palce in the stack trace and handle them as last very thing.
使用 DependencyResolver.Current 绝对是解决 ASP .NET MVC 中问题的一种方法,因为它是一个框架功能。但是,我首先尝试遵循 “最佳实践”中的以下建议” Autofac Wiki 部分
“授予组件访问容器的权限,将其存储在公共静态属性中,或者使 Resolve() 之类的函数在全局“IoC”类上可用,违背了使用依赖关系的目的此类设计与服务定位器模式有更多共同点。
如果组件对容器有依赖关系,请查看它们如何使用容器来检索服务,并将这些服务添加到组件的(依赖项注入的)构造函数参数中。
对需要实例化其他组件或以更高级的方式与容器交互的组件使用关系类型。”
仅当无法按照上面的建议重述依赖项时,我才会使用 DependencyResolver。
Using DependencyResolver.Current is definitely a way of solving your problem in ASP .NET MVC given that it is a framework feature. However, I would first try to follow the following recommendation from the "Best Practices" section of the Autofac Wiki
"Giving components access to the container, storing it in a public static property, or making functions like Resolve() available on a global 'IoC' class defeats the purpose of using dependency injection. Such designs have more in common with the Service Locator pattern.
If components have a dependency on the container, look at how they're using the container to retrieve services, and add those services to the component's (dependency injected) constructor arguments instead.
Use relationship types for components that need to instantiate other components or interact with the container in more advanced ways."
Only if not possible to restate a dependency as suggested above would I use the DependencyResolver.
寻找此问题的其他解决方案的人可能会看看另一个利用
IComponentContext< 的 SO 答案 /code> 由 Autofac 直接注入的解析器服务。
People looking for another solution to this issue might have a look at this other SO answer that takes advantage of
IComponentContext
resolver service injected directly by Autofac.