Skip to content

Commit

Permalink
Do not reuse ExternalComponentRegistration
Browse files Browse the repository at this point in the history
Fixes #960
  • Loading branch information
sandersaares authored and alexmg committed Feb 18, 2019
1 parent f50cd07 commit cb91ecd
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 4 deletions.
4 changes: 0 additions & 4 deletions src/Autofac/Core/Registration/ExternalRegistrySource.cs
Expand Up @@ -68,13 +68,9 @@ public IEnumerable<IComponentRegistration> RegistrationsFor(Service service, Fun

// Issue #272: Taking from the registry the following registrations:
// - non-adapting own registrations: wrap them with ExternalComponentRegistration
// - if the registration is from the parent registry of this registry,
// it is already wrapped with ExternalComponentRegistration,
// share it as is
return _registry.RegistrationsFor(service)
.Where(r => r is ExternalComponentRegistration || !r.IsAdapting())
.Select(r =>
r as ExternalComponentRegistration ??
// equivalent to following registation builder
// RegistrationBuilder.ForDelegate(r.Activator.LimitType, (c, p) => c.ResolveComponent(r, p))
Expand Down
26 changes: 26 additions & 0 deletions test/Autofac.Test/Core/Registration/ExternalRegistrySourceTests.cs
Expand Up @@ -36,5 +36,31 @@ public void OneTypeImplementTwoInterfaces_OtherObjectsImplementingOneOfThoseInte
var allImplementationsOfServiceA = lifetime.Resolve<IEnumerable<IServiceA>>();
Assert.Equal(2, allImplementationsOfServiceA.Count());
}

// Issue #960
[Fact]
public void TwoLayersOfExternalRegistration_OnDisposingInnerLayer_OuterLayerRemains()
{
var builder = new ContainerBuilder();
builder.RegisterType<ClassA>().InstancePerLifetimeScope();

// Root has the main registration.
var root = builder.Build();

// Middle has ExternalRegistration pointing upwards.
var middle = root.BeginLifetimeScope(cb => cb.Register(_ => new object()));
middle.Resolve<ClassA>();

// Child has ExternalRegistration pointing upwards.
var child = middle.BeginLifetimeScope(cb => cb.Register(_ => new object()));
child.Resolve<ClassA>();

// This should only dispose the registration in child, not the one in middle.
child.Dispose();

// We check by trying to use the registration in middle.
// If too much got disposed, this will throw ObjectDisposedException.
middle.Resolve<ClassA>();
}
}
}

0 comments on commit cb91ecd

Please sign in to comment.