zcz527 / autofac

Automatically exported from code.google.com/p/autofac
Other
0 stars 0 forks source link

Nested lifetime scope with overriden service - cannot resolve all implementations of a service #282

Closed GoogleCodeExporter closed 8 years ago

GoogleCodeExporter commented 8 years ago
What steps will reproduce the problem?
1. Create a class (ClassA) that implements 2 services (say ServiceA and 
ServiceAB)
2. Create another class (ClassB) that implements 1 service (ServiceA)
3. Configure container with both classes registered
4. Begin new lifetime scope, but override any service (so that separate 
component registry is created)
5. Resolve ClassA, referencing service B (e.g. 
lifetimeScope.Resolve<ServiceB[]>())
6. Try to resolve all implementations of service A 
(lifetimeScope.Resolve<ServiceA[]>())

What is the expected output? What do you see instead?
Expected: both implementations - ClassA and ClassB
Actual: only ClassA object

Failing test:
        interface ServiceA { }
        interface ServiceB { }
        class ClassA : ServiceA, ServiceB { }
        class ClassB : ServiceA { }
        [Test]
        public void OneTypeImplementTwoInterfaces_OtherObjectsImplementingOneOfThoseInterfaces_CanBeResolved()
        {
            var builder = new ContainerBuilder();
            builder.RegisterType(typeof(ClassA)).As(typeof(ServiceA), typeof(ServiceB));
            builder.RegisterType(typeof(ClassB)).As(typeof(ServiceA));

            var container = builder.Build();
            var lifetime = container.BeginLifetimeScope(cb => cb.Register(_ => ""));
            lifetime.Resolve<ServiceB>();

            var allImplementationsOfServiceA = lifetime.Resolve<IEnumerable<ServiceA>>();
            Assert.AreEqual(2, allImplementationsOfServiceA.Count());
        }

I was able to pinpoint this issue to the code in 
ComponentRegistry.GetInitializedServiceInfo - the part that prevents multiple 
registration of same component also prevents other implementations of the 
service to be registered in nested LifetimeScope that has separate component 
registry. I was trying to solve this, however, the only viable solution I 
thought of is to add equality comparison to IComponentRegistration. Then, 
AddRegistration method could simply check for duplicates before adding.

Original issue reported on code.google.com by m.kowale...@ela.pl on 7 Jan 2011 at 3:01

GoogleCodeExporter commented 8 years ago
Thank you very much for reporting this, along with the investigation and the 
repro. I'll do my best to figure it out.
Cheers,
Nick

Original comment by nicholas...@gmail.com on 8 Jan 2011 at 4:03

GoogleCodeExporter commented 8 years ago
Fixed in trunk via a workaround in ExternalRegistrySource. Some more 
investigation is required into how/where this affects other features. We'll 
watch and wait for now. Thanks again!

Original comment by nicholas...@gmail.com on 9 Jan 2011 at 12:29