I have an infrastructure singleton that I would like resolved out of autofac
At container creation I register AppPaths
as a singleton
However, for a variety of reasons (testing, a few infrastructure things) I would like to be able to swap that instance out with a new one during runtime. Let's say a derived type class AppPaths2 : AppPaths
.
I can't find the API to do this.
I can use CommentServiceLocator to get an instance of IComponentContext
but I don't see a way to resolve stuff from there.
You can use Action<T>
to change the value of your current variable.
Foo foo = new Foo();
builder.RegisterInstance(foo);
builder.Register<Action<Foo>>(c => newFoo => foo = newFoo);
Then, you will be able to change current Foo
using :
Action<Foo> fooUpdater = c.Resolve<Action<Foo>>()();
fooUpdater(new Foo());
You can also use a 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();
Another solution is to update the container :
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
}
But doing so will only add a new registration to the component registry. If you resolve IEnumerable<Foo>
you will have all your implementations.