繁体   English   中英

使用 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
));

或者它是否会起作用。

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

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

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

ILifetimeScopeAutofac 中自动注册,您无需为其添加注册。

有关更多信息,请参阅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 { }

尝试针对容器解析 IComponentContext ;)

虽然我没有回答你的问题。 尝试在服务类中获取容器的句柄或者除了相当于IModule之外的任何东西都是代码味道。

您的服务代码不应该了解IOC IMO。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM