Решением может быть предоставление этих пользовательских сервисов для жизненного диапазона при создании области действия. При создании новой области действия с помощью container.BeginLifetimeScope
вы можете указать дополнительный параметр Action<ContainerBuilder>
, чтобы определить некоторые пользовательские регистрации для этой конкретной области действия.
Таким образом, для вашего кода вместо глобальной регистрации для ChildB
вы можете переместить его в область регистрации. Это может выглядеть примерно так:
[TestMethod]
public void NamedLifetimeTests()
{
var builder = new ContainerBuilder();
builder.Register(c => new ChildA()).As<Parent>().InstancePerLifetimeScope();
var container = builder.Build();
using (var scope = container.BeginLifetimeScope())
{
var parent = scope.Resolve<Parent>();
Assert.IsTrue(parent.GetType() == typeof(ChildA));
}
using (var scope = container.BeginLifetimeScope("system"), cb => { cb.RegisterType<ChildB>().As<Parent>(); }))
{
var parent = scope.Resolve<Parent>();
Assert.IsTrue(parent.GetType() == typeof(ChildB));
}
}
EDIT:
Избегать введения объема жизни понятно. Другим решением может быть выбор правильной реализации, основанной на теге области действия, аналогично выбору реализации на основе параметра, описанного в docs :
// omitted ...
var builder = new ContainerBuilder();
builder.Register<Parent>(c =>
{
var currentScope = c.Resolve<ILifetimeScope>();
if (currentScope.Tag?.ToString() == "system")
{
return new ChildB();
}
return new ChildA();
}).InstancePerLifetimeScope();
var container = builder.Build();
// omitted ...