Using Autofac as a service locator

11,024

Solution 1

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.

Solution 2

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.

Share:
11,024
David Pfeffer
Author by

David Pfeffer

I'm the CTO of the startup company FunnelFire, where we build a sophisticated real-time sales intelligence platform. I'm also an adjunct professor of Computer Science at Stevens Institute of Technology, where I teach a variety of courses from Introduction to C++11, to Data Structure and Algorithms, to TCP/IP Networking (an advanced programming course where students re-implement the network stack). I graduated in 2009 from Stevens Institute of Technology with a bachelors and masters of science in Computer Science, a minor in Law & Public Policy, and graduate certificates in Computer Systems, Databases & Service Oriented Architecture, Distributed Systems, Enterprise Computing, Quantitative Software Engineering, and Service Oriented Computing. I got my start programming at a very young age, writing QBasic programs to display colorful circles on the screen while sitting on my dad's lap when I was 3 years old. My first big projects were a Super Mario World clone for GameBoy, a MUD called HybridMOO, and a home automation package called IntellHome (which I still use!). I'm actively involved in a number of open source initiatives, including an open-source middleware tool called PushoverQ. I am interested in hiking, exploration of abandoned or neglected sites and buildings, photography (particularly of those abandoned sites, but also glamour/editorial), cooking, snowshoeing, and New Jersey trivia/history.

Updated on June 04, 2022

Comments

  • David Pfeffer
    David Pfeffer almost 2 years

    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?

  • David Pfeffer
    David Pfeffer over 12 years
    Will this work with multiple lifetime scopes? i.e. Will the IComponentContext be the base Container or the scope?
  • Peter Lillevold
    Peter Lillevold over 12 years
    It will resolve IComponentContext from the scope in which MyComponent was resolved. So if MyComponent is registered as InstancePerLifetimeScope, context will always resolve from the expected scope.
  • David Pfeffer
    David Pfeffer over 12 years
    I'm not sure why you'd answer an already well-answered question with stuff that isn't related to my question at all... as I said, my issue is not knowing which "B" I will need to resolve until runtime.
  • rsenna
    rsenna about 12 years
    @NikosBaxevanis +1, even if the OP didn't seem to get it. Both posts are excellent. This single phrase from Nicholas post resumes it all: "At the same time, there’s practically no excuse to use IContainer or IComponentContext in your components anymore".