I want to override the transient (or scoped) registration within the (nested) scope. Is this possible? I found I can achieve that with IScope.Use for instances, but how to achieve that for transients?
Consider the situation when you can optionally choose from several customizations, that overrides some feature implementations. The standard implementation is registered within the parent scope, and a nested scope is created for the chosen customization that re-registers the affected interfaces with its own implementations. When different customization is chosen the previous nested scope is disposed and a new one is created with different registrations.
[Test]
public void ScopedTransientDryIOC()
{
var container = new Container(scopeContext: new AsyncExecutionFlowScopeContext());
container.Register<IFeature, StandardFeature>(reuse: Reuse.Transient);
var standardFeature = container.Resolve<IFeature>();
Assert.That(standardFeature, Is.TypeOf<StandardFeature>(), "In container");
using (var scope1 = container.OpenScope("scope1"))
{
// Without overriding resolves the standard implementation from the parent scope
var customizedFeature = container.Resolve<IFeature>();
Assert.That(
customizedFeature,
Is.TypeOf<StandardFeature>(),
"In OpenScope 1st level, before local registration");
// Such a function does not exists. Is there any workaround?
scope1.Register<IFeature, CustomizedFeature>(reuse: Reuse.Transient);
// After overriding it should resolve the customized implementation
customizedFeature = container.Resolve<IFeature>();
Assert.That(
customizedFeature,
Is.TypeOf<CustomizedFeature>(),
"In OpenScope 1st level, after local registration");
}
// When the overriding scope is disposed resolve again the standard implementation from the root scope
var standardFeatureClosed = container.Resolve<IFeature>();
Assert.That(standardFeatureClosed , Is.TypeOf<StandardFeature>(), "After 1st level scope disposed");
}
public interface IFeature {}
public class StandardFeature : IFeature {}
public class CustomizedFeature : IFeature {}
The answer is utilizing the Child Container: