Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Using Autofac as a service locator

I'm using Autofac to handle dependency injection in my application. However, I have one component that does some reflection magic at runtime and I don't know at compile-time what dependencies it will need.

Ordinarily, I would just have this component reference the Container directly and resolve whatever it wants. However, the class that is instantiating this class has no reference to the Container.

Effectively, my component has a dependency on Autofac. I'd prefer looser coupling, but that doesn't seem to be an option here. Is there a way to ask (in the constructor args, or using property injection, or whatever!) Autofac to give me a reference to the container in my constructor? Or, is there a cleaner way to have Autofac provide me with a magic service locator object that can resolve anything?

like image 555
David Pfeffer Avatar asked Aug 25 '11 13:08

David Pfeffer


People also ask

Is Autofac a service locator?

The Autofac. Extras. CommonServiceLocator package allows you to use Autofac as the backing store for services in places where you require Microsoft Common Service Locator integration.

What is Autofac container?

Autofac is an addictive IoC container for . NET. It manages the dependencies between classes so that applications stay easy to change as they grow in size and complexity. This is achieved by treating regular . NET classes as components.

What is Servicelocator in C#?

The Service Locator is a pattern by which we can reduce the dependency of one object on another that we will see shortly and Dependency injection (DI) is another smart solution for the same problem.


2 Answers

Yes, you can. Just take a dependency on the IComponentContext:

public class MyComponent
{
    IComponentContext _context;
    public MyComponent(IComponentContext context)
    {
        _context = context;
    }

    public void DoStuff()
    {
        var service = _context.Resolve(...);
    }
}

Update from the comments: the IComponentContext injected into MyComponent depends on the scope from which MyComponent was resolved. It is thus important to consider with what lifetime scope MyComponent is registered. E.g. using InstancePerLifetimeScope, the context will always resolve to the same scope in which the service depending on MyComponent lives.

like image 127
Peter Lillevold Avatar answered Sep 18 '22 09:09

Peter Lillevold


Supposing you have two components, A and B.

If A needs to know X about B before using it, this is Metadata interrogation and it is described in this excellent post.

Furthermore, even if you can't adapt your design to that post, you should again try to make sure if you really need to use your DI Container as a Service Locator.

At the time of this writting, the best blog post I could find describing it is this one.

like image 44
Nikos Baxevanis Avatar answered Sep 20 '22 09:09

Nikos Baxevanis