From a7c446bbbf8aaafe5d1c5522e9dea66242628142 Mon Sep 17 00:00:00 2001 From: Danny Van den Wouwer Date: Mon, 16 Nov 2020 16:28:53 +0100 Subject: [PATCH] Fix CollectionResolver.cs, honor inline dependencies if kernel propagate it (#561) --- ...esolverWithPropagatingContainerTestCase.cs | 122 ++++++++++++++++++ .../CollectionResolver.cs | 10 +- 2 files changed, 127 insertions(+), 5 deletions(-) create mode 100644 src/Castle.Windsor.Tests/SpecializedResolvers/CollectionResolverWithPropagatingContainerTestCase.cs diff --git a/src/Castle.Windsor.Tests/SpecializedResolvers/CollectionResolverWithPropagatingContainerTestCase.cs b/src/Castle.Windsor.Tests/SpecializedResolvers/CollectionResolverWithPropagatingContainerTestCase.cs new file mode 100644 index 0000000000..eb9ba29647 --- /dev/null +++ b/src/Castle.Windsor.Tests/SpecializedResolvers/CollectionResolverWithPropagatingContainerTestCase.cs @@ -0,0 +1,122 @@ +// Copyright 2004-2020 Castle Project - http://www.castleproject.org/ +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +namespace Castle.MicroKernel.Tests.SpecializedResolvers +{ + using System; + using System.Reflection; + + using Castle.MicroKernel.Context; + using Castle.MicroKernel.Registration; + using Castle.MicroKernel.Resolvers; + using Castle.Windsor; + using Castle.Windsor.Installer; + using Castle.Windsor.Proxy; + + using NUnit.Framework; + + public class CollectionResolverWithPropagatingContainerTestCase + : CollectionResolverTestCase + { + /// Build a container, where all are propagating. + /// A Castle Windsor container + protected override WindsorContainer BuildContainer() + { + return + new WindsorContainer( + new DefaultKernel( + new InlineDependenciesPropagatingDependencyResolver(), + new DefaultProxyFactory()), + new DefaultComponentInstaller()); + } + + [Test] + public void collection_sub_resolver_should_honor_composition_context_if_kernel_propagates_inline_dependencies() + { + Container.Register(Component.For().LifestyleTransient()); + Container.Register(Component.For().ImplementedBy().LifestyleTransient()); + Container.Register(Component.For().ImplementedBy().LifestyleTransient()); + + var additionalArguments = Arguments.FromProperties(new { greeting = "Hello propagating system." }); + var componentA = Kernel.Resolve(additionalArguments); + Assert.That(componentA, Is.Not.Null); + Assert.That(componentA.Greeting, Is.Not.Null); + Assert.That(componentA.ComponentsOfB, Is.Not.Null); + Assert.That(componentA.ComponentsOfB.Length, Is.EqualTo(2)); + foreach (IComponentB componentB in componentA.ComponentsOfB) + { + Assert.That(componentA.Greeting, Is.EqualTo(componentB.Greeting)); + } + } + + public class InlineDependenciesPropagatingDependencyResolver + : DefaultDependencyResolver + { + protected override CreationContext RebuildContextForParameter( + CreationContext current, + Type parameterType) + { + return parameterType.GetTypeInfo().ContainsGenericParameters + ? current + : new CreationContext(parameterType, current, true); + } + } + + public class ComponentA + { + public ComponentA( + IKernel kernel, + IComponentB[] componentsOfB, + string greeting) + { + Kernel = kernel; + ComponentsOfB = componentsOfB; + Greeting = greeting; + } + + public IKernel Kernel { get; } + public IComponentB[] ComponentsOfB { get; } + public string Greeting { get; } + } + + public interface IComponentB + { + string Greeting { get; } + } + + public abstract class ComponentB : IComponentB + { + protected ComponentB(string greeting) + { + Greeting = greeting; + } + + public string Greeting { get; } + } + + public class ComponentB1 : ComponentB + { + public ComponentB1(string greeting) : base(greeting) + { + } + } + + public class ComponentB2 : ComponentB + { + public ComponentB2(string greeting) : base(greeting) + { + } + } + } +} diff --git a/src/Castle.Windsor/MicroKernel/Resolvers/SpecializedResolvers/CollectionResolver.cs b/src/Castle.Windsor/MicroKernel/Resolvers/SpecializedResolvers/CollectionResolver.cs index 30c23d74a3..f60da201f4 100644 --- a/src/Castle.Windsor/MicroKernel/Resolvers/SpecializedResolvers/CollectionResolver.cs +++ b/src/Castle.Windsor/MicroKernel/Resolvers/SpecializedResolvers/CollectionResolver.cs @@ -1,11 +1,11 @@ // Copyright 2004-2011 Castle Project - http://www.castleproject.org/ -// +// // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at -// +// // http://www.apache.org/licenses/LICENSE-2.0 -// +// // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. @@ -57,7 +57,7 @@ public virtual bool CanResolve(CreationContext context, ISubDependencyResolver c public virtual object Resolve(CreationContext context, ISubDependencyResolver contextHandlerResolver, ComponentModel model, DependencyModel dependency) { - return kernel.ResolveAll(GetItemType(dependency.TargetItemType), null); + return kernel.ResolveAll(GetItemType(dependency.TargetItemType), context.AdditionalArguments); } protected virtual bool CanSatisfy(Type itemType) @@ -75,4 +75,4 @@ protected virtual bool HasParameter(DependencyModel dependency) return dependency.Parameter != null; } } -} \ No newline at end of file +}