diff --git a/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs b/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs
index c316083c..b0ec3266 100644
--- a/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/ObjectFactoryUtils.cs
@@ -122,22 +122,19 @@ namespace Spring.Objects.Factory
/// The array of object names, or an empty array if none.
public static string[] ObjectNamesIncludingAncestors(IListableObjectFactory factory)
{
- Set result = new HashedSet();
- result.AddAll(factory.GetObjectDefinitionNames());
+ ArrayList result = new ArrayList();
+ result.AddRange(factory.GetObjectDefinitionNames());
IListableObjectFactory pof = GetParentFactoryIfAny(factory);
if (pof != null)
{
string[] parentsResult = ObjectNamesIncludingAncestors(pof);
- result.AddAll(parentsResult);
+ foreach (string s in parentsResult)
+ {
+ if (!result.Contains(s)) result.Add(s);
+ }
}
- return ToArrayOfObjectNames(result);
- }
-
- private static string[] ToArrayOfObjectNames(Set result)
- {
- Array resultArray = Array.CreateInstance(typeof (string), result.Count);
- result.CopyTo(resultArray, 0);
- return (string[]) resultArray;
+ //return ToArrayOfObjectNames(result);
+ return (string[]) result.ToArray(typeof (string));
}
///
@@ -179,15 +176,21 @@ namespace Spring.Objects.Factory
IListableObjectFactory factory, Type type,
bool includePrototypes, bool includeFactoryObjects)
{
- Set result = new HashedSet();
- result.AddAll(factory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects));
+ ArrayList result = new ArrayList();
+ result.AddRange(factory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects));
IListableObjectFactory pof = GetParentFactoryIfAny(factory);
if (pof != null)
{
string[] parentsResult = ObjectNamesForTypeIncludingAncestors(pof, type, includePrototypes, includeFactoryObjects);
- result.AddAll(parentsResult);
+ foreach(string s in parentsResult)
+ {
+ if (!result.Contains(s))
+ {
+ result.Add(s);
+ }
+ }
}
- return ToArrayOfObjectNames(result);
+ return (string[]) result.ToArray(typeof (string));
}
///
@@ -221,15 +224,21 @@ namespace Spring.Objects.Factory
public static string[] ObjectNamesForTypeIncludingAncestors(
IListableObjectFactory factory, Type type)
{
- Set result = new HashedSet();
- result.AddAll(factory.GetObjectNamesForType(type));
+ ArrayList result = new ArrayList();
+ result.AddRange(factory.GetObjectNamesForType(type));
IListableObjectFactory pof = GetParentFactoryIfAny(factory);
if (pof != null)
{
string[] parentsResult = ObjectNamesForTypeIncludingAncestors(pof, type);
- result.AddAll(parentsResult);
+ foreach(string s in parentsResult)
+ {
+ if (!result.Contains(s))
+ {
+ result.Add(s);
+ }
+ }
}
- return ToArrayOfObjectNames(result);
+ return (string[]) result.ToArray(typeof (string));
}
private static IListableObjectFactory GetParentFactoryIfAny(IListableObjectFactory factory)
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
index 0cbd2ec1..1adbf103 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
@@ -140,6 +140,7 @@ namespace Spring.Objects.Factory.Support
{
this.log = LogManager.GetLogger( this.GetType() );
this.caseSensitive = caseSensitive;
+#if NET_1_0 || NET_1_1
if (caseSensitive)
{
this.aliasMap = new Hashtable();
@@ -152,6 +153,12 @@ namespace Spring.Objects.Factory.Support
this.singletonCache = new CaseInsensitiveHashtable();
this.singletonsInCreation = new CaseInsensitiveHashtable();
}
+#else
+ IEqualityComparer comparer = (caseSensitive) ? StringComparer.Ordinal : StringComparer.OrdinalIgnoreCase;
+ this.aliasMap = new OrderedDictionary(comparer);
+ this.singletonCache = new OrderedDictionary(comparer);
+ this.singletonsInCreation = new OrderedDictionary(comparer);
+#endif
}
///
@@ -1253,7 +1260,8 @@ namespace Spring.Objects.Factory.Support
{
lock (singletonCache)
{
- return (string[])new ArrayList( singletonCache.Keys ).ToArray( typeof( string ) );
+ ICollection keys = singletonCache.Keys;
+ return (string[])new ArrayList( keys ).ToArray( typeof( string ) );
}
}
diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/AbstractObjectFactoryTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/AbstractObjectFactoryTests.cs
index 33bfd7b2..8adda77e 100644
--- a/test/Spring/Spring.Core.Tests/Objects/Factory/AbstractObjectFactoryTests.cs
+++ b/test/Spring/Spring.Core.Tests/Objects/Factory/AbstractObjectFactoryTests.cs
@@ -80,7 +80,13 @@ namespace Spring.Objects.Factory
protected internal abstract AbstractObjectFactory CreateObjectFactory(bool caseSensitive);
- protected AbstractObjectFactory ObjectFactory { get { return CreateObjectFactory(true); } }
+ private AbstractObjectFactory cachedFactory;
+
+ protected AbstractObjectFactory ObjectFactory
+ {
+ get { return cachedFactory; }
+ set { cachedFactory = value; }
+ }
#endregion
@@ -448,6 +454,23 @@ namespace Spring.Objects.Factory
.RegisterSingleton(null, DBNull.Value);
}
+ [Test]
+ public void GetSingletonNamesReflectsOrderOfRegistration()
+ {
+ AbstractObjectFactory of;
+ of = CreateObjectFactory(true);
+ of.RegisterSingleton("A", new object());
+ of.RegisterSingleton("C", new object());
+ of.RegisterSingleton("B", new object());
+ Assert.AreEqual(new string[] { "A", "C", "B"}, of.GetSingletonNames());
+
+ of = CreateObjectFactory(false);
+ of.RegisterSingleton("A", new object());
+ of.RegisterSingleton("C", new object());
+ of.RegisterSingleton("B", new object());
+ Assert.AreEqual(new string[] { "A", "C", "B"}, of.GetSingletonNames(typeof(object)));
+ }
+
[Test]
[ExpectedException(typeof(ArgumentNullException))]
public void ContainsSingletonWithEmptyName()
diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectFactoryUtilsTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectFactoryUtilsTests.cs
index f955b16b..2b95d7a3 100644
--- a/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectFactoryUtilsTests.cs
+++ b/test/Spring/Spring.Core.Tests/Objects/Factory/ObjectFactoryUtilsTests.cs
@@ -23,6 +23,7 @@
using System;
using System.Collections;
using NUnit.Framework;
+using Rhino.Mocks;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Xml;
@@ -74,8 +75,28 @@ namespace Spring.Objects.Factory
Assert.AreEqual(6, names.Count);
}
+ [Test]
+ public void ObjectNamesIncludingAncestorsPreserveOrderOfRegistration()
+ {
+ MockRepository mocks = new MockRepository();
+ IConfigurableListableObjectFactory of = (IConfigurableListableObjectFactory) mocks.DynamicMock(typeof (IConfigurableListableObjectFactory));
+ IConfigurableListableObjectFactory ofParent = (IConfigurableListableObjectFactory) mocks.DynamicMock(typeof (IConfigurableListableObjectFactory));
+
+ using(mocks.Record())
+ {
+ Expect.Call(of.GetObjectDefinitionNames()).Return(new string[] { "objA", "objB", "objC" });
+ Expect.Call(((IHierarchicalObjectFactory)of).ParentObjectFactory).Return(ofParent);
+ Expect.Call(ofParent.GetObjectDefinitionNames()).Return(new string[] { "obj2A", "objB", "obj2C" });
+ }
+
+ string[] names = ObjectFactoryUtils.ObjectNamesIncludingAncestors(of);
+ Assert.AreEqual(5, names.Length);
+ Assert.AreEqual(new string[] { "objA","objB","objC","obj2A","obj2C" }, names);
+ mocks.ReplayAll();
+ }
+
[Test]
- public void ObjectNamesForType()
+ public void ObjectNamesForTypeIncludingAncestors()
{
IList names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, typeof (ITestObject));
// includes 2 TestObjects from IFactoryObjects (DummyFactory definitions)
@@ -86,6 +107,48 @@ namespace Spring.Objects.Factory
Assert.IsTrue(names.Contains("testFactory2"));
}
+ [Test]
+ public void ObjectNamesForTypeIncludingAncestorsPreserveOrderOfRegistration()
+ {
+ MockRepository mocks = new MockRepository();
+ IConfigurableListableObjectFactory of = (IConfigurableListableObjectFactory)mocks.DynamicMock(typeof(IConfigurableListableObjectFactory));
+ IConfigurableListableObjectFactory ofParent = (IConfigurableListableObjectFactory)mocks.DynamicMock(typeof(IConfigurableListableObjectFactory));
+ Type EXPECTEDTYPE = typeof (ITestObject);
+
+ using (mocks.Record())
+ {
+ Expect.Call(of.GetObjectNamesForType(EXPECTEDTYPE)).Return(new string[] { "objA", "objB", "objC" });
+ Expect.Call(((IHierarchicalObjectFactory)of).ParentObjectFactory).Return(ofParent);
+ Expect.Call(ofParent.GetObjectNamesForType(EXPECTEDTYPE)).Return(new string[] { "obj2A", "objB", "obj2C" });
+ }
+
+ string[] names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(of, EXPECTEDTYPE);
+ Assert.AreEqual(5, names.Length);
+ Assert.AreEqual(new string[] { "objA", "objB", "objC", "obj2A", "obj2C" }, names);
+ mocks.ReplayAll();
+ }
+
+ [Test]
+ public void ObjectNamesForTypeIncludingAncestorsPrototypesAndFactoryObjectsPreserveOrderOfRegistration()
+ {
+ MockRepository mocks = new MockRepository();
+ IConfigurableListableObjectFactory of = (IConfigurableListableObjectFactory)mocks.DynamicMock(typeof(IConfigurableListableObjectFactory));
+ IConfigurableListableObjectFactory ofParent = (IConfigurableListableObjectFactory)mocks.DynamicMock(typeof(IConfigurableListableObjectFactory));
+ Type EXPECTEDTYPE = typeof(ITestObject);
+
+ using (mocks.Record())
+ {
+ Expect.Call(of.GetObjectNamesForType(EXPECTEDTYPE, false, false)).Return(new string[] { "objA", "objB", "objC" });
+ Expect.Call(((IHierarchicalObjectFactory)of).ParentObjectFactory).Return(ofParent);
+ Expect.Call(ofParent.GetObjectNamesForType(EXPECTEDTYPE, false, false)).Return(new string[] { "obj2A", "objB", "obj2C" });
+ }
+
+ string[] names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(of, EXPECTEDTYPE, false, false);
+ Assert.AreEqual(5, names.Length);
+ Assert.AreEqual(new string[] { "objA", "objB", "objC", "obj2A", "obj2C" }, names);
+ mocks.ReplayAll();
+ }
+
[Test]
public void CountObjectsIncludingAncestorsWithNonHierarchicalFactory()
{
diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlListableObjectFactoryTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlListableObjectFactoryTests.cs
index a2ff36bd..44abdc76 100644
--- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlListableObjectFactoryTests.cs
+++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlListableObjectFactoryTests.cs
@@ -71,13 +71,11 @@ namespace Spring.Objects.Factory.Xml
protected internal override AbstractObjectFactory CreateObjectFactory(bool caseSensitive)
{
- return (caseSensitive)
- ? factory
- : new DefaultListableObjectFactory(caseSensitive);
+ return new DefaultListableObjectFactory(caseSensitive);
}
private DefaultListableObjectFactory parent;
- private XmlObjectFactory factory;
+// private XmlObjectFactory factory;
#region Test SetUp
@@ -100,14 +98,16 @@ namespace Spring.Objects.Factory.Xml
UnsupportedObjectDefinitionImplementation unsupportedDefinition = new UnsupportedObjectDefinitionImplementation();
parent.RegisterObjectDefinition("unsupportedDefinition", unsupportedDefinition);
- this.factory = new XmlObjectFactory(new ReadOnlyXmlTestResource("test.xml", GetType()), parent);
+ XmlObjectFactory factory;
+ factory = new XmlObjectFactory(new ReadOnlyXmlTestResource("test.xml", GetType()), parent);
// TODO: should this be allowed?
//this.factory.RegisterObjectDefinition("typedfather", new RootObjectDefinition(typeof(object), false));
- this.factory.AddObjectPostProcessor(new AnonymousClassObjectPostProcessor());
- this.factory.AddObjectPostProcessor(new LifecycleObject.PostProcessor());
+ factory.AddObjectPostProcessor(new AnonymousClassObjectPostProcessor());
+ factory.AddObjectPostProcessor(new LifecycleObject.PostProcessor());
- this.factory.PreInstantiateSingletons();
+ factory.PreInstantiateSingletons();
+ base.ObjectFactory = factory;
}
#endregion
@@ -166,7 +166,7 @@ namespace Spring.Objects.Factory.Xml
[Test]
public virtual void CountSingletons()
{
- Assert.AreEqual(10, factory.GetSingletonCount(), "Number of singletons incorrect");
+ Assert.AreEqual(10, ObjectFactory.GetSingletonCount(), "Number of singletons incorrect");
}
}
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs
index f67425b9..9a8ead40 100644
--- a/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs
+++ b/test/Spring/Spring.Core.Tests/Objects/Factory/Xml/XmlObjectFactoryTests.cs
@@ -23,6 +23,7 @@
using System;
using System.Collections;
using System.Data;
+using System.Diagnostics;
using System.Globalization;
using System.IO;
using System.Text;