Autofac を使用してコンテナー自体を登録する

インスタンスが初期化される前にインスタンスを登録するため、コードは安全ではありません。

コンポーネント内のコンテナーにアクセスする必要がある場合 (これは良い考えではありません)、 ILifetimeScope に依存できます。 Resolve を持っているもの メソッド。

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

ILifetimeScope Autofac 内に自動的に登録されます 登録を追加する必要はありません。

Autofac からのスコープと有効期間の制御を参照してください 詳細については、ドキュメントを参照してください。

ところで、IoC コンテナーに依存することはお勧めできません。 Service Locator アンチパターンを使用しているようです。コンテナーに遅延ロードの依存関係が必要な場合は、Func<T> でコンポジションを使用できます。 または Lazy<T>

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

    private readonly Lazy<MyService> _myService;
}

この場合、MyService 最初にアクセスしたときに作成されます。

Autofac からの暗黙の関係を参照してください 詳細についてはドキュメントをご覧ください。


この拡張メソッドを使用できます:

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

次のように使用します:builder.RegisterSelf();


コンテナのインスタンスを builder.RegisterInstance() に提供する必要があるため 、現在行っていない引数として渡す前に初期化する必要があります。ただし、登録 (およびコンテナーの初期化) 後にビルドするようにコンテナー ビルダーを構成すると、クラス内のコンテナー インスタンスを正常に解決できます。

これは間違いなく依存性注入の設計臭であり、絶対にこれを行うべきではないことに注意してください。コンテナー/カーネルは、オブジェクト グラフの最上位にのみ存在する必要があります。コンテナへの注入を開始すると、ほぼ確実に 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 { }