インスタンスが初期化される前にインスタンスを登録するため、コードは安全ではありません。
コンポーネント内のコンテナーにアクセスする必要がある場合 (これは良い考えではありません)、 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 { }