使用 Autofac 注册容器本身

Register Container Itself Using Autofac

我想知道在自身内部注册容器是否有任何副作用

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

和这样使用它

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

或者它是否有效。

由于您需要向 builder.RegisterInstance() 提供容器实例,因此您需要在将其作为参数传递之前对其进行初始化,而您目前并未这样做。但是,如果您构建容器构建器以在注册(和容器初始化)后构建,则可以成功解析 class.

中的容器实例

请注意,这肯定是依赖注入中的设计味道,您绝对不应该这样做。您的 container/kernel 应该只存在于对象图的顶层。如果您开始注入您的容器,您几乎可以肯定正在使用服务定位器反模式。

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 { }

您的代码不安全,因为您在初始化之前注册了一个实例。

如果您需要访问组件内的容器(这不是一个好主意),您可以依赖具有 Resolve 方法的 ILifetimeScope

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

ILifetimeScope 会在 Autofac 中自动注册,您无需为其添加注册。

有关详细信息,请参阅 Autofac 文档中的 Controlling Scope and Lifetime

顺便说一句,依赖 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 文档中的 Implicit Relationship

您可以使用此扩展方法:

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

这样使用:builder.RegisterSelf();

尝试根据容器解析 IComponentContext ;)