Registra il contenitore stesso utilizzando Autofac

Registra il contenitore stesso utilizzando Autofac

Il tuo codice non è sicuro perché registri un'istanza prima che sia stata inizializzata.

Se hai bisogno di accedere al contenitore all'interno di un componente (che non è una buona idea) puoi avere una dipendenza da ILifetimeScope che hanno Resolve metodi.

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

ILifetimeScope viene registrato automaticamente in AutoFac non è necessario aggiungere la registrazione per questo.

Consulta Controllo dell'ambito e della durata da Autofac documentazione per ulteriori informazioni.

A proposito, non è una buona pratica avere una dipendenza dal tuo contenitore IoC. Sembra che tu usi l'anti-modello di Service Locator. Se hai bisogno del contenitore per la dipendenza dal carico pigro, puoi utilizzare la composizione con Func<T> o Lazy<T>

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

    private readonly Lazy<MyService> _myService;
}

In questo caso, MyService verrà creato al primo accesso.

Vedi Relazione implicita da Autofac documentazione per ulteriori informazioni.


Puoi utilizzare questo metodo di estensione:

public static void RegisterSelf(this ContainerBuilder builder)
{
    IContainer container = null;
    builder.Register(c => container).AsSelf().SingleInstance();
    builder.RegisterBuildCallback(c => container = c);
}

usalo in questo modo:builder.RegisterSelf();


Poiché devi fornire un'istanza del contenitore a builder.RegisterInstance() , devi inizializzarlo PRIMA di passarlo come argomento, cosa che al momento non stai facendo. Tuttavia, se strutturi il tuo generatore di container per creare DOPO la registrazione (e l'inizializzazione del container), puoi risolvere correttamente l'istanza del container nella tua classe.

Tieni presente che questo è sicuramente un odore di design in Dependency Injection e non dovresti assolutamente farlo. Il tuo contenitore/kernel dovrebbe esistere solo al livello superiore del tuo grafico a oggetti. Se inizi a iniettare il tuo contenitore, sei quasi sicuramente sulla buona strada per un Service Locator Anti-Pattern.

void Main()
{
    IContainer container = new ContainerBuilder().Build();
    ContainerBuilder builder = new ContainerBuilder();

    builder.RegisterInstance(container).As<IContainer>();

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

    container = builder.Build();
    var instance = container.Resolve<IManagmentServiceImp>();
}

public class ManagementServiceImp : IManagmentServiceImp 
{ 
    private IContainer _container;

    public ManagementServiceImp(IContainer Container)
    {
        _container = Container;
        _container.Dump();
    }
}

public interface IManagmentServiceImp { }