diff --git a/src/Autofac.Configuration/Util/TypeManipulation.cs b/src/Autofac.Configuration/Util/TypeManipulation.cs index 7fdd01d..11459c6 100644 --- a/src/Autofac.Configuration/Util/TypeManipulation.cs +++ b/src/Autofac.Configuration/Util/TypeManipulation.cs @@ -129,7 +129,7 @@ public static object ChangeToCompatibleType(object value, Type destinationType, converter = GetTypeConverterFromName(converterAttribute.ConverterTypeName); if (converter.CanConvertFrom(value.GetType())) { - return converter.ConvertFrom(value); + return converter.ConvertFrom(null, CultureInfo.InvariantCulture, value); } } @@ -137,14 +137,14 @@ public static object ChangeToCompatibleType(object value, Type destinationType, converter = TypeDescriptor.GetConverter(value.GetType()); if (converter.CanConvertTo(destinationType)) { - return converter.ConvertTo(value, destinationType); + return converter.ConvertTo(null, CultureInfo.InvariantCulture, value, destinationType); } // Try explicit opposite conversion. converter = TypeDescriptor.GetConverter(destinationType); if (converter.CanConvertFrom(value.GetType())) { - return converter.ConvertFrom(value); + return converter.ConvertFrom(null, CultureInfo.InvariantCulture, value); } // Try a TryParse method. diff --git a/test/Autofac.Configuration.Test/Core/ConfigurationExtensions_EnumerableParametersFixture.cs b/test/Autofac.Configuration.Test/Core/ConfigurationExtensions_EnumerableParametersFixture.cs index af48f2e..34ac98f 100644 --- a/test/Autofac.Configuration.Test/Core/ConfigurationExtensions_EnumerableParametersFixture.cs +++ b/test/Autofac.Configuration.Test/Core/ConfigurationExtensions_EnumerableParametersFixture.cs @@ -1,5 +1,6 @@ using System.Collections; using System.Collections.Generic; +using System.Globalization; using System.Linq; using Xunit; @@ -37,8 +38,8 @@ public void ConvertsTypeInList() var poco = container.Resolve(); Assert.True(poco.List.Count == 2); - Assert.Equal(1, poco.List[0]); - Assert.Equal(2, poco.List[1]); + Assert.Equal(1.234, poco.List[0]); + Assert.Equal(2.345, poco.List[1]); } public class C @@ -54,8 +55,8 @@ public void FillsNonGenericListWithString() var poco = container.Resolve(); Assert.True(poco.List.Count == 2); - Assert.Equal("1", poco.List[0]); - Assert.Equal("2", poco.List[1]); + Assert.Equal("1.234", poco.List[0]); + Assert.Equal("2.345", poco.List[1]); } public class D @@ -70,7 +71,7 @@ public void InjectsSingleValueWithConversion() var poco = container.Resolve(); - Assert.True(poco.Num == 123); + Assert.Equal(123.456, poco.Num); } public class E @@ -91,8 +92,28 @@ public void InjectsConstructorParameter() var poco = container.Resolve(); Assert.True(poco.List.Count == 2); - Assert.Equal(1, poco.List[0]); - Assert.Equal(2, poco.List[1]); + Assert.Equal(1.234, poco.List[0]); + Assert.Equal(2.345, poco.List[1]); + } + + [Theory] + [MemberData(nameof(ParsingCultures))] + public void TypeConversionsAreCaseInvariant(CultureInfo culture) + { + // Issue #26 - parsing needs to be InvariantCulture or config fails + // when it's moved from machine to machine. + TestCulture.With( + culture, + () => + { + var container = EmbeddedConfiguration.ConfigureContainerWithXml("ConfigurationExtensions_EnumerableParameters.xml").Build(); + + var poco = container.Resolve(); + + Assert.True(poco.List.Count == 2); + Assert.Equal(1.234, poco.List[0]); + Assert.Equal(2.345, poco.List[1]); + }); } public class G @@ -129,8 +150,8 @@ public void InjectsGenericIEnumerable() Assert.NotNull(poco.Enumerable); var enumerable = poco.Enumerable.ToList(); Assert.True(enumerable.Count == 2); - Assert.Equal(1, enumerable[0]); - Assert.Equal(2, enumerable[1]); + Assert.Equal(1.234, enumerable[0]); + Assert.Equal(2.345, enumerable[1]); } public class I @@ -147,8 +168,8 @@ public void InjectsGenericCollection() Assert.NotNull(poco.Collection); Assert.True(poco.Collection.Count == 2); - Assert.Equal(1, poco.Collection.First()); - Assert.Equal(2, poco.Collection.Last()); + Assert.Equal(1.234, poco.Collection.First()); + Assert.Equal(2.345, poco.Collection.Last()); } public class J @@ -243,5 +264,13 @@ public void ParameterStringListInjectionSecondElementHasNoName() // Val2 is dropped from the configuration when it's parsed. Assert.Collection(poco.List, v => Assert.Equal("Val1", v)); } + + public static IEnumerable ParsingCultures() + { + yield return new object[] { new CultureInfo("en-US") }; + yield return new object[] { new CultureInfo("es-MX") }; + yield return new object[] { new CultureInfo("it-IT") }; + yield return new object[] { CultureInfo.InvariantCulture }; + } } } diff --git a/test/Autofac.Configuration.Test/Files/ConfigurationExtensions_EnumerableParameters.xml b/test/Autofac.Configuration.Test/Files/ConfigurationExtensions_EnumerableParameters.xml index 19a8f99..58c09cb 100644 --- a/test/Autofac.Configuration.Test/Files/ConfigurationExtensions_EnumerableParameters.xml +++ b/test/Autofac.Configuration.Test/Files/ConfigurationExtensions_EnumerableParameters.xml @@ -1,96 +1,96 @@ - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+A - - Val1 - Val2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+B - - 1 - 2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+C - - 1 - 2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+D - - 123 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+E - - 1 - 2 - - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+G - - Val1 - Val2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+H - - 1 - 2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+I - - 1 - 2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+J - - Val1 - Val2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+K - - Val1 - Val2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+L - - Val1 - Val2 - - - - Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+M - - Val1 - Val2 - - - + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+A + + Val1 + Val2 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+B + + 1.234 + 2.345 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+C + + 1.234 + 2.345 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+D + + 123.456 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+E + + 1.234 + 2.345 + + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+G + + Val1 + Val2 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+H + + 1.234 + 2.345 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+I + + 1.234 + 2.345 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+J + + Val1 + Val2 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+K + + Val1 + Val2 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+L + + Val1 + Val2 + + + + Autofac.Configuration.Test.Core.ConfigurationExtensions_EnumerableParametersFixture+M + + Val1 + Val2 + + + diff --git a/test/Autofac.Configuration.Test/TestCulture.cs b/test/Autofac.Configuration.Test/TestCulture.cs new file mode 100644 index 0000000..48d5f29 --- /dev/null +++ b/test/Autofac.Configuration.Test/TestCulture.cs @@ -0,0 +1,31 @@ +using System; +using System.Globalization; +using System.Threading; +using Xunit; + +namespace Autofac.Configuration.Test +{ + public static class TestCulture + { + public static void With(CultureInfo culture, Action test) + { + var originalCulture = Thread.CurrentThread.CurrentCulture; + var originalUICulture = Thread.CurrentThread.CurrentUICulture; + Thread.CurrentThread.CurrentCulture = culture; + Thread.CurrentThread.CurrentUICulture = culture; + CultureInfo.CurrentCulture.ClearCachedData(); + CultureInfo.CurrentUICulture.ClearCachedData(); + try + { + test(); + } + finally + { + Thread.CurrentThread.CurrentCulture = originalCulture; + Thread.CurrentThread.CurrentUICulture = originalUICulture; + CultureInfo.CurrentCulture.ClearCachedData(); + CultureInfo.CurrentUICulture.ClearCachedData(); + } + } + } +} \ No newline at end of file diff --git a/test/Autofac.Configuration.Test/Util/TypeManipulationFixture.cs b/test/Autofac.Configuration.Test/Util/TypeManipulationFixture.cs index bbe0080..b9ec0dd 100644 --- a/test/Autofac.Configuration.Test/Util/TypeManipulationFixture.cs +++ b/test/Autofac.Configuration.Test/Util/TypeManipulationFixture.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; @@ -59,6 +60,27 @@ public void ChangeToCompatibleType_NoConversionNeeded() Assert.Equal(15, actual); } + [Theory] + [MemberData(nameof(ParsingCultures))] + public void ChangeToCompatibleType_UsesInvariantCulture(CultureInfo culture) + { + TestCulture.With( + culture, + () => + { + var actual = TypeManipulation.ChangeToCompatibleType("123.456", typeof(double)); + Assert.Equal(123.456, actual); + }); + } + + public static IEnumerable ParsingCultures() + { + yield return new object[] { new CultureInfo("en-US") }; + yield return new object[] { new CultureInfo("es-MX") }; + yield return new object[] { new CultureInfo("it-IT") }; + yield return new object[] { CultureInfo.InvariantCulture }; + } + public class Convertible { public int Value { get; set; }