Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Global access to autofac dependency resolver in ASP.NET MVC3?

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

like image 353
Typo Johnson Avatar asked Apr 25 '11 11:04

Typo Johnson


3 Answers

The thing you're looking for is MVC's DependencyResolver.Current:

var logger = DependencyResolver.Current.GetService<ILogger>();
like image 195
Nicholas Blumhardt Avatar answered Oct 23 '22 02:10

Nicholas Blumhardt


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.

like image 20
Boris Bucha Avatar answered Oct 23 '22 03:10

Boris Bucha


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.

like image 42
Ruben Ramirez Padron Avatar answered Oct 23 '22 03:10

Ruben Ramirez Padron