Skip to content

Commit

Permalink
Fix #1204 - Capture instance at the point of injection, rather than u…
Browse files Browse the repository at this point in the history
…sing the final instance from the request context.
  • Loading branch information
alistairjevans committed Sep 28, 2020
1 parent 0aa6e7a commit 6cd646c
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
Expand Up @@ -584,11 +584,13 @@ public RegistrationBuilder(Service defaultService, TActivatorData activatorData,
if (allowCircularDependencies)
{
var capturedInstance = ctxt.Instance;
// If we are allowing circular deps, then we need to run when all requests have completed (similar to Activated).
ctxt.RequestCompleting += (o, args) =>
{
var evCtxt = args.RequestContext;
AutowiringPropertyInjector.InjectProperties(evCtxt, evCtxt.Instance!, propertySelector, evCtxt.Parameters);
AutowiringPropertyInjector.InjectProperties(evCtxt, capturedInstance!, propertySelector, evCtxt.Parameters);
};
}
else
Expand Down
49 changes: 49 additions & 0 deletions test/Autofac.Specification.Test/Features/PropertyInjectionTests.cs
Expand Up @@ -373,6 +373,22 @@ public void SetterInjectionPrivateGet()
Assert.False(instance.GetterCalled);
}

[Fact]
public void DecoratedInstanceWithPropertyInjectionAllowingCircularReferencesStillInjects()
{
var val = "Value";

var builder = new ContainerBuilder();
builder.RegisterInstance(val);
builder.RegisterType<DecoratedService>().As<IMyService>().PropertiesAutowired(PropertyWiringOptions.AllowCircularDependencies);
builder.RegisterDecorator<ServiceDecorator, IMyService>();

var container = builder.Build();
var instance = container.Resolve<IMyService>();

instance.AssertProp();
}

private class ConstructorParamNotAttachedToProperty
{
[SuppressMessage("SA1401", "SA1401")]
Expand Down Expand Up @@ -411,5 +427,38 @@ private get
}
}
}

private interface IMyService
{
void AssertProp();
}

private sealed class DecoratedService : IMyService
{
public string Prop { get; set; }

public void AssertProp()
{
if (Prop is null)
{
throw new NullReferenceException();
}
}
}

private sealed class ServiceDecorator : IMyService
{
private readonly IMyService _decorating;

public ServiceDecorator(IMyService decorating)
{
_decorating = decorating;
}

public void AssertProp()
{
_decorating.AssertProp();
}
}
}
}

0 comments on commit 6cd646c

Please sign in to comment.