diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs b/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs index 2668a89f..8a7b3e38 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Config/TypedStringValue.cs @@ -21,122 +21,193 @@ #region Imports using System; -using Spring.Util; - -#endregion - -namespace Spring.Objects.Factory.Config -{ - /// - /// Holder for a typed value. - /// - /// - ///

- /// Can be added to object definitions to explicitly specify - /// a target type for a value, - /// for example for collection - /// elements. - ///

- ///

- /// This holder just stores the value and the target - /// . The actual conversion will be performed by - /// the surrounding object factory. - ///

- ///
- /// Juergen Hoeller - /// Rick Evans (.NET) - [Serializable] - public class TypedStringValue - { - #region Constructor (s) / Destructor - - /// - /// Creates a new instance of the - /// - /// class. - /// - public TypedStringValue() - { - } - - /// - /// Initializes a new instance of the class. - /// - /// The value. - public TypedStringValue(string value) - { - Value = value; - } - - /// - /// Creates a new instance of the - /// - /// class. - /// - /// - /// The value that is to be converted. - /// - /// - /// The to convert to. - /// - /// - /// If the supplied is - /// . - /// - public TypedStringValue(string value, Type targetType) - { - Value = value; - TargetType = targetType; - } - - #endregion - - /// - /// The value that is to be converted. - /// - /// - ///

- /// Obviously if the - /// - /// is the , no conversion - /// will actually be performed. - ///

- ///
- public string Value - { - get { return theValue; } - set { this.theValue = value; } - } - - /// - /// The to convert to. - /// - /// - /// If the setter is supplied with a value. - /// - public Type TargetType - { - get { return targetType; } - set - { - AssertUtils.ArgumentNotNull(value, "TargetType"); - targetType = value; - } - } - - /// - /// Gets a value indicating whether this instance has target type. - /// - /// - /// true if this instance has target type; otherwise, false. - /// - public bool HasTargetType - { - get { return targetType != null; } - } - - private string theValue; - private Type targetType; - } +using Spring.Util; +using Spring.Core.TypeResolution; +#endregion + +namespace Spring.Objects.Factory.Config +{ + /// + /// Holder for a typed value. + /// + /// + ///

+ /// Can be added to object definitions to explicitly specify + /// a target type for a value, + /// for example for collection + /// elements. + ///

+ ///

+ /// This holder just stores the value and the target + /// . The actual conversion will be performed by + /// the surrounding object factory. + ///

+ ///
+ /// Juergen Hoeller + /// Rick Evans (.NET) + /// Bruno Baia (.NET) + [Serializable] + public class TypedStringValue + { + private string theValue; + private object targetType; + + #region Constructor (s) / Destructor + + /// + /// Creates a new instance of the + /// + /// class. + /// + public TypedStringValue() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The value. + public TypedStringValue(string value) + { + Value = value; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The value that is to be converted. + /// + /// + /// The to convert to. + /// + /// + /// If the supplied is + /// . + /// + public TypedStringValue(string value, Type targetType) + { + Value = value; + TargetType = targetType; + } + + /// + /// Creates a new instance of the + /// + /// class. + /// + /// + /// The value that is to be converted. + /// + /// + /// The unresolved type to convert to. + /// + /// + /// If the supplied is a + /// or an empty string. + /// + public TypedStringValue(string value, string targetTypeName) + { + Value = value; + TargetTypeName = targetTypeName; + } + + #endregion + + /// + /// The value that is to be converted. + /// + /// + ///

+ /// Obviously if the + /// + /// is the , no conversion + /// will actually be performed. + ///

+ ///
+ public string Value + { + get { return theValue; } + set { this.theValue = value; } + } + + /// + /// The to convert to. + /// + /// + /// If the setter is supplied with a value. + /// + public Type TargetType + { + get + { + if (!HasTargetType) + { + throw new ApplicationException( + "Typed String value does not carry a resolved System.Type"); + } + return (Type)targetType; + } + set + { + AssertUtils.ArgumentNotNull(value, "TargetType"); + targetType = value; + } + } + + /// + /// The unresolved type to convert to. + /// + /// + /// If the setter is supplied with a value or an empty string. + /// + public string TargetTypeName + { + get + { + if (targetType is Type) + { + return ((Type) targetType).FullName; + } + else + { + return targetType as string; + } + } + set + { + AssertUtils.ArgumentHasText(value, "TargetTypeName"); + targetType = value; + } + } + + /// + /// Gets a value indicating whether this instance has target type. + /// + /// + /// true if this instance has target type; otherwise, false. + /// + public bool HasTargetType + { + get { return targetType is Type; } + } + + /// + /// Determine the type to convert to, resolving it from a specified type name if necessary. + /// + /// The resolved type to convert to. + public Type ResolveTargetType() + { + if (this.targetType == null) + { + return null; + } + Type resolvedType = TypeResolutionUtils.ResolveType(this.TargetTypeName); + this.targetType = resolvedType; + return resolvedType; + } + } } \ No newline at end of file diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs index 4c591745..ae126116 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs @@ -239,14 +239,11 @@ namespace Spring.Objects.Factory.Support /// The resolved target type, if any. otherwise. protected virtual Type ResolveTargetType(TypedStringValue value) { - if (value.HasTargetType) + if (value.HasTargetType) { - return value.TargetType; - } - else - { - return null; + return value.TargetType; } + return value.ResolveTargetType(); } /// diff --git a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs index 3d4c5174..49380724 100644 --- a/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs +++ b/src/Spring/Spring.Core/Objects/Factory/Xml/ObjectsNamespaceParser.cs @@ -1003,15 +1003,7 @@ namespace Spring.Objects.Factory.Xml } else { - Type resolvedValueType = TypeResolutionUtils.ResolveType(valueType); - if (resolvedValueType == typeof(string)) - { - return ParseTextValueElement(element, name); - } - else - { - return new TypedStringValue(ParseTextValueElement(element, name), resolvedValueType); - } + return new TypedStringValue(ParseTextValueElement(element, name), valueType); } } diff --git a/test/Spring/Spring.Core.Tests/Data/Spring/Objects/Factory/Config/TypeAliases.xml b/test/Spring/Spring.Core.Tests/Data/Spring/Objects/Factory/Config/TypeAliases.xml index 6f905130..df95671a 100644 --- a/test/Spring/Spring.Core.Tests/Data/Spring/Objects/Factory/Config/TypeAliases.xml +++ b/test/Spring/Spring.Core.Tests/Data/Spring/Objects/Factory/Config/TypeAliases.xml @@ -5,6 +5,7 @@ + @@ -19,4 +20,12 @@ + + + + + 30 + + + \ No newline at end of file diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypeAliasConfigurerTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypeAliasConfigurerTests.cs index bda6dde5..c4ed3aff 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypeAliasConfigurerTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypeAliasConfigurerTests.cs @@ -124,6 +124,13 @@ namespace Spring.Objects.Factory.Config Assert.AreEqual(typeof(TestObject), obj3.GetType()); Assert.AreEqual("Bruno", ((TestObject)obj3).Name); Assert.AreEqual(26, ((TestObject)obj3).Age); + + // SPRNET-1119 + object obj4 = ctx.GetObject("testObject4"); + Assert.IsNotNull(obj4); + Assert.AreEqual(typeof(TestObject), obj4.GetType()); + Assert.AreEqual("Bruno", ((TestObject)obj4).Name); + Assert.AreEqual(30, ((TestObject)obj4).Age); } private void CreateConfigurerAndTestLinkedList(IDictionary typeAliases) diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs index ad67be66..93fa2722 100644 --- a/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs +++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Config/TypedStringValueTests.cs @@ -40,20 +40,41 @@ namespace Spring.Objects.Factory.Config public void Instantiation() { string expectedNow = DateTime.Now.ToShortDateString(); - TypedStringValue tsv = new TypedStringValue(expectedNow, typeof (DateTime)); + + TypedStringValue tsv = new TypedStringValue(expectedNow, typeof (DateTime)); Assert.AreEqual(expectedNow, tsv.Value); Assert.AreEqual(typeof (DateTime), tsv.TargetType); + tsv = new TypedStringValue(expectedNow); Assert.AreEqual(expectedNow, tsv.Value); + + tsv = new TypedStringValue(expectedNow, typeof(DateTime).FullName); + Assert.AreEqual(expectedNow, tsv.Value); + Assert.AreEqual(typeof(DateTime).FullName, tsv.TargetTypeName); + } [Test] [ExpectedException(typeof (ArgumentNullException))] public void InstantiationWithNullType() { - new TypedStringValue(string.Empty, null); + new TypedStringValue(string.Empty, (Type)null); } + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void InstantiationWithNullTypeName() + { + new TypedStringValue(string.Empty, (string)null); + } + + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void InstantiationWithEmptyTypeName() + { + new TypedStringValue(string.Empty, " "); + } + [Test] [ExpectedException(typeof (ArgumentNullException))] public void SetTargetTypePropertyToNullType() @@ -62,6 +83,14 @@ namespace Spring.Objects.Factory.Config tsv.TargetType = null; } + [Test] + [ExpectedException(typeof(ArgumentNullException))] + public void SetTargetTypeNamePropertyToEmptyString() + { + TypedStringValue tsv = new TypedStringValue(string.Empty, typeof(DateTime)); + tsv.TargetTypeName = " "; + } + [Test] public void IsSerializable() { @@ -88,5 +117,33 @@ namespace Spring.Objects.Factory.Config Assert.AreEqual(expectedValue, deser.Value, "Serialization roundtrip yielded the wrong Value."); } + + [Test] + public void HasTargetType() + { + TypedStringValue tsv = new TypedStringValue(string.Empty, typeof(DateTime)); + Assert.IsTrue(tsv.HasTargetType); + } + + [Test] + public void HasTargetTypeReturnsFalseWhenTargetTypeNotResolved() + { + TypedStringValue tsv = new TypedStringValue(string.Empty, typeof(DateTime).FullName); + Assert.IsFalse(tsv.HasTargetType); + + tsv = new TypedStringValue(string.Empty, typeof(DateTime)); + Assert.IsTrue(tsv.HasTargetType); + tsv.TargetTypeName = typeof(DateTime).FullName; + Assert.IsFalse(tsv.HasTargetType); + } + + [Test] + public void ResolveTargetType() + { + TypedStringValue tsv = new TypedStringValue(string.Empty, typeof(DateTime).FullName); + Assert.IsFalse(tsv.HasTargetType); + Assert.AreEqual(typeof(DateTime), tsv.ResolveTargetType()); + Assert.IsTrue(tsv.HasTargetType); + } } } \ No newline at end of file