创建容器后如何使用 autofac 注册类型

How to register a type with autofac after container creation

我有一个基础架构单例,我想从 autofac 中解决

在创建容器时,我将 AppPaths 注册为单例

但是,出于各种原因(测试、一些基础设施方面的事情),我希望能够在运行时用新实例替换该实例。假设派生类型 class AppPaths2 : AppPaths.

我找不到 API 来执行此操作。

我可以使用 CommentServiceLocator 获取 IComponentContext 的实例,但我看不到从那里解决问题的方法。

您可以使用 Action<T> 更改当前变量的值。

Foo foo = new Foo();
builder.RegisterInstance(foo);
builder.Register<Action<Foo>>(c => newFoo => foo = newFoo);

然后,您将能够更改电流 Foo 使用:

Action<Foo> fooUpdater = c.Resolve<Action<Foo>>()(); 
fooUpdater(new Foo());

您也可以使用 FooContainer

class FooContainer
{
    public FooContainer(Foo originalValue)
    {
        this.Value = originalValue;
    }
    public Foo Value { get; set; }
}

// ...

builder.RegisterType<FooContainer>().SingleInstance();
builder.Register(c => c.Resolve<FooContainer>().Value).As<Foo>();

// ...

c.Resolve<FooContainer>().Value = new Foo(); 

另一个解决方案是更新容器:

ContainerBuilder builder = new ContainerBuilder();
builder.RegisterInstance(new Foo()).AsSelf();
IContainer container = builder.Build();

using (ILifetimeScope scope = container.BeginLifetimeScope())
{
    ContainerBuilder updater = new ContainerBuilder();
    updater.RegisterInstance(new Foo()).AsSelf(); // new instance of Foo
    updater.Update(scope.ComponentRegistry);

    scope.Resolve<Foo>(); // ==> new instance of Foo
}

但是这样做只会在组件注册表中添加一个新的注册。如果您解决 IEnumerable<Foo>,您将拥有所有实施。