Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix XML configuration dictionary containing list of components throws exceptions #575

Merged
merged 6 commits into from
Dec 4, 2020
Merged
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ Bugfixes:
- Fix CollectionResolver to allow propagation of inline dependencies (@dvdwouwe, #562)
- Allow DefaultNamingSubSystem derivatives to invalidate the cache which was accidently removed in 5.1.0 (@nativenolde, #569)
- Replace usage of obsolete Castle.Core.Internal.Lock (@generik0, #576)
- Fix dictionary bug when using XML configuration; A reference to list components inside a dictionary didn't work (@ni-mi, #575)

## 5.1.0 (2020-11-16)

Expand Down
88 changes: 87 additions & 1 deletion src/Castle.Windsor.Tests/Config/ConfigurationTestCase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@

namespace Castle.MicroKernel.Tests.Configuration
{
using System.Collections.Generic;

using Castle.Core;
using Castle.Core.Configuration;
using Castle.Core.Resource;
Expand All @@ -33,6 +35,91 @@ namespace Castle.MicroKernel.Tests.Configuration
[TestFixture]
public class ConfigurationTestCase : AbstractContainerTestCase
{
[Test]
[Bug("https://github.com/castleproject/Windsor/issues/574")]
public void DictionaryWithReferencedProperty()
{
var config =
@"
<configuration>
<properties>
<value1>Property Value 1</value1>
<value2>Property Value 2</value2>
</properties>
<components>
<component id='stringToStringDictionary' type='System.Collections.Generic.Dictionary`2[System.String, System.String]'>
<parameters>
<dictionary>
<dictionary>
<entry key='Key 1'>#{value1}</entry>
<entry key='Key 2'>#{value2}</entry>
</dictionary>
</dictionary>
</parameters>
</component>
</components>
</configuration>";

Container.Install(Configuration.FromXml(new StaticContentResource(config)));
var stringToStringDictionary = Container.Resolve<Dictionary<string, string>>("stringToStringDictionary");
Assert.NotNull(stringToStringDictionary);
Assert.AreEqual(2, stringToStringDictionary.Count);
Assert.AreEqual("Property Value 1", stringToStringDictionary["Key 1"]);
Assert.AreEqual("Property Value 2", stringToStringDictionary["Key 2"]);
}

[Test]
[Bug("https://github.com/castleproject/Windsor/issues/574")]
public void DictionaryWithReferencedList()
{
var config =
@"
<configuration>
<facilities>
</facilities>
<components>
<component id='list' type='System.Collections.Generic.List`1[[System.String]]'>
<parameters>
<collection>
<array>
<item>11</item>
<item>12</item>
</array>
</collection>
</parameters>
</component>

<component id='list2' type='System.Collections.Generic.List`1[[System.String]]'>
<parameters>
<collection>
<array>
<item>21</item>
<item>22</item>
</array>
</collection>
</parameters>
</component>

<component id='stringToListDictionary' type='System.Collections.Generic.Dictionary`2[System.String, System.Collections.Generic.List`1[[System.String]]]'>
<parameters>
<dictionary>
<dictionary>
<entry key='Key 1'>${list}</entry>
<entry key='Key 2'>${list2}</entry>
</dictionary>
</dictionary>
</parameters>
</component>
</components>
</configuration>";

Container.Install(Configuration.FromXml(new StaticContentResource(config)));
var stringsList = Container.Resolve<List<string>>("list");
var stringToListDictionary = Container.Resolve<Dictionary<string, List<string>>>("stringToListDictionary");
Assert.NotNull(stringToListDictionary);
Assert.AreEqual(2, stringToListDictionary.Count);
}

[Test]
[Bug("IOC-155")]
public void Type_not_implementing_service_should_throw()
Expand Down Expand Up @@ -128,7 +215,6 @@ public void ShouldNotThrowCircularDependencyException()
Assert.NotNull(user.EmptyService);
}


[Test]
public void Can_properly_populate_array_dependency_from_xml_config_when_registering_by_convention()
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ namespace Castle.MicroKernel.SubSystems.Conversion

using Castle.Core.Configuration;
using Castle.Core.Internal;
using Castle.MicroKernel.Context;
using Castle.MicroKernel.Util;

[Serializable]
public class GenericListConverter : AbstractTypeConverter
Expand All @@ -42,6 +44,17 @@ public override bool CanHandleType(Type type)

public override object PerformConversion(String value, Type targetType)
{
if (ReferenceExpressionUtil.IsReference(value))
{
string newValue = ReferenceExpressionUtil.ExtractComponentName(value);
var handler = Context.Kernel.LoadHandlerByName(newValue, targetType, null);
if (handler == null)
{
throw new ConverterException(string.Format("Component '{0}' was not found in the container.", newValue));
}

return handler.Resolve(Context.CurrentCreationContext ?? CreationContext.CreateEmpty());
}
throw new NotImplementedException();
}

Expand Down