I have two scopes, one nested inside the other. When I resolve a particular service, I would like one component to be resolved in one root scope and a different one in the child scope. Is there an easy way of doing this?
I have managed to get something working using a factory class that determines what the current scope is and then returning the appropriate instance:
IContainer BuildContainer()
{
var builder = new ContainerBuilder();
// ...
builder.RegisterType<FooInParentScope>().AsSelf();
builder.RegisterType<FooInChildScope>().AsSelf();
builder.RegisterType<FooFactory>().AsImplementedInterfaces();
builder.Register<IFoo>(c => c.Resolve<IFooFactory>().GetFoo()).InstancePerLifetimeScope();
// ...
}
class FooFactory : IFooFactory
{
private readonly ILifetimeScope m_scope;
public FooFactory(ILifetimeScope scope)
{
m_scope = scope;
}
public IFoo GetFoo()
{
if (m_scope.Tag == "ParentScope")
return m_scope.Resolve<FooInParentScope>();
else
return m_scope.Resolve<FooInChildScope>();
}
}
class FooInParentScope : IFoo
{
}
class FooInChildScope : IFoo
{
}
There are a number of issues with this approach:
Autofac.Core.Lifetime.LifetimeScope
and examining the ParentLifetimeScope
property, but that is probably not a particularly safe thing to do.You may register FooInParentScope in root container as SingleInstance. And when creating inner lifetimescope add registration for FooInChildScope as SingleInstance (override registration).
builder.RegisterType<FooInParentScope>().As<IFoo>.SingleInstance();
var container = builder.Build();
var childScope = container.BeginLifetimeScope(innerBuilder =>
{
// override registration for IFoo in child lifetime scope:
innerBuilder.RegisterType<FooInChildScope>().As<IFoo>().SingleInstance();
});
FooInParentScope fooInParentScope = (FooInParentScope) container.Resolve<IFoo>();
FooInChildScope fooInChildScope = (FooInChildScope) childScope.Resolve<IFoo>();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With