Register Container Itself Using Autofac

Scarnet picture Scarnet · Apr 24, 2016 · Viewed 15.7k times · Source

I was wondering is there's any side effect to registering the container within itself

IContainer container;
ContainerBuilder builder = new ContainerBuilder();
container = builder.Build();
builder.RegisterInstance(container).As<IContainer>();

and the using it like this

builder.RegisterType<IManagmentServiceImp>().As<ManagmentServiceImp>()
    .WithParameter(new ResolvedParameter(
            (pi, ctx) => pi.ParameterType == typeof(IContainer) && pi.Name == "Container",
            (pi, ctx) => container
));

or whether it will even work.

Answer

Cyril Durand picture Cyril Durand · Apr 24, 2016

Your code is not safe because you register an instance before it has been initialized.

If you need to have access to the container inside a component (which is not a good idea) you can have a dependency on ILifetimeScope which have Resolve methods.

public class ManagmentServiceImp 
{
    public ManagmentServiceImp(ILifetimeScope scope)
    {
    }
}

ILifetimeScope is automatically registered within Autofac you don't need to add registration for it.

See Controlling Scope and Lifetime from Autofac documentation for more information.

By the way, it is not a good practice to have dependency on your IoC container. It looks like you use Service Locator anti-pattern. If you need the container to lazy load dependency, you can use composition with Func<T> or Lazy<T>

public class ManagmentServiceImp 
{
    public ManagmentServiceImp(Lazy<MyService> myService)
    {
        this._myService = myService; 
    }

    private readonly Lazy<MyService> _myService;
}

In this case, MyService will be created when you first access it.

See Implicit Relationship from the Autofac documentation for more information.