SPRNET-694

-updated so-called "anonymous child containers" to be assigned deterministic naming of the form "parent/nestedContainer1/nestedContainer2/nestedContainer3/etc"
-prior changes already prevent the actual error reported in this issue by throwing if two contexts are attempted to be registered with the same names
This commit is contained in:
sbohlen
2010-08-04 19:56:30 +00:00
parent c756336427
commit 11816bf43b
3 changed files with 151 additions and 2 deletions

View File

@@ -27,6 +27,8 @@ using System.Configuration;
using Common.Logging;
using Spring.Context.Events;
using Spring.Util;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Support;
#endregion
@@ -102,6 +104,51 @@ namespace Spring.Context.Support
get { return syncRoot; }
}
private static void ConstructNestedDefaultContextName(IApplicationContext context)
{
IApplicationContext parent = context.ParentContext;
Hashtable contexts = new Hashtable();
int contextIndex = 0;
contexts.Add(contextIndex, context);
while (parent != null)
{
contextIndex++;
contexts.Add(contextIndex, parent);
parent = parent.ParentContext;
}
string prefix = string.Empty;
for (int i = contextIndex; i > 0; i--)
{
IApplicationContext contextToUpdate = (IApplicationContext)contexts[i];
if (prefix != string.Empty)
prefix = string.Format("{0}/{1}", prefix, contextToUpdate.Name);
else
prefix = contextToUpdate.Name;
}
context.Name = string.Format("{0}/{1}", prefix, context.Name);
}
private static void EnsureHierarchicalNameIfDefault(IApplicationContext context)
{
//if there is no parent context there is no change needed
if (context.ParentContext == null)
return;
if (context.Name == AbstractApplicationContext.DefaultRootContextName)
ConstructNestedDefaultContextName(context);
}
/// <summary>
/// Registers an instance of an
/// <see cref="Spring.Context.IApplicationContext"/>.
@@ -119,6 +166,9 @@ namespace Spring.Context.Support
/// </exception>
public static void RegisterContext(IApplicationContext context)
{
EnsureHierarchicalNameIfDefault(context);
lock (syncRoot)
{
if (instance.contextMap.Contains(context.Name))

View File

@@ -254,9 +254,17 @@ namespace Spring.Context
_mockName = name;
factory = new DefaultListableObjectFactory();
// factory.AddObjectPostProcessor(new ApplicationContextAwareProcessor(this));
}
}
public MockApplicationContext(string name, IApplicationContext parentContext) : base(name, true, parentContext)
/// <summary>
/// Initializes a new instance of the MockApplicationContext class.
/// </summary>
public MockApplicationContext(IApplicationContext parentContext)
{
factory = new DefaultListableObjectFactory(parentContext);
}
public MockApplicationContext(string name, IApplicationContext parentContext) : base(name, true, parentContext)
{
_mockName = name;
factory = new DefaultListableObjectFactory(GetInternalParentObjectFactory());

View File

@@ -249,6 +249,7 @@ namespace Spring.Context.Support
ContextRegistry.RegisterContext(duplicate);
}
[Test]
public void RemovesContextFromRegistryWhenContextCloses()
{
@@ -259,5 +260,95 @@ namespace Spring.Context.Support
appCtx.Dispose();
Assert.IsFalse(ContextRegistry.IsContextRegistered(appCtx.Name));
}
[TestFixture]
public class WhenHierarchicalContextsAllHaveDefaultNames
{
private MockApplicationContext _parentContext;
private MockApplicationContext _childContext;
private MockApplicationContext _grandChildContext;
private MockApplicationContext _greatGrandChildContext;
private string _expectedParentName;
private string _expectedChildName;
private string _expectedGrandChildName;
private string _expectedGreatGrandChildName;
[TestFixtureSetUp]
public void InitializeAllTests()
{
_expectedParentName = AbstractApplicationContext.DefaultRootContextName;
_expectedChildName = string.Format("{0}/{1}", _expectedParentName, AbstractApplicationContext.DefaultRootContextName);
_expectedGrandChildName = string.Format("{0}/{1}/{2}",_expectedParentName, _expectedChildName, AbstractApplicationContext.DefaultRootContextName);
_expectedGreatGrandChildName = string.Format("{0}/{1}/{2}/{3}",_expectedParentName, _expectedChildName, _expectedGrandChildName, AbstractApplicationContext.DefaultRootContextName);
}
[SetUp]
public void Setup()
{
//ensure prior-registered contexts are removed
ContextRegistry.Clear();
_parentContext = new MockApplicationContext();
_parentContext.MockName = "parent";
_childContext = new MockApplicationContext(_parentContext);
_childContext.MockName = "child";
_childContext.ParentContext = _parentContext;
_grandChildContext = new MockApplicationContext(_childContext);
_grandChildContext.MockName = "grandchild";
_grandChildContext.ParentContext = _childContext;
_greatGrandChildContext = new MockApplicationContext(_grandChildContext);
_greatGrandChildContext.MockName = "greatgrandchild";
_greatGrandChildContext.ParentContext = _grandChildContext;
}
[Test]
public void RegisterContext_ConstructsNestedPathBasedNames_IfRegisterdInHierarchicalOrder()
{
ContextRegistry.RegisterContext(_parentContext);
ContextRegistry.RegisterContext(_childContext);
ContextRegistry.RegisterContext(_grandChildContext);
ContextRegistry.RegisterContext(_greatGrandChildContext);
Assert.AreEqual(_expectedParentName, ContextRegistry.GetContext().Name);
Assert.AreEqual(_expectedChildName, ContextRegistry.GetContext(_expectedChildName).Name);
Assert.AreEqual(_expectedGrandChildName, ContextRegistry.GetContext(_expectedGrandChildName).Name);
Assert.AreEqual(_expectedGreatGrandChildName, ContextRegistry.GetContext(_expectedGreatGrandChildName).Name);
}
[Test]
public void RegisterContext_ConstructsNestedPathBasedNames_IfRegisteringAMixOfDefaultAndExplicitNamedContexts()
{
//modify the expected names for the decendent contexts for this one test
string childContextInitialName = AbstractApplicationContext.DefaultRootContextName + "_CUSTOM";
_expectedChildName = string.Format("{0}/{1}", _expectedParentName, childContextInitialName);
_expectedGrandChildName = string.Format("{0}/{1}/{2}", _expectedParentName, _expectedChildName, AbstractApplicationContext.DefaultRootContextName);
_expectedGreatGrandChildName = string.Format("{0}/{1}/{2}/{3}", _expectedParentName, _expectedChildName, _expectedGrandChildName, AbstractApplicationContext.DefaultRootContextName);
//setup custom child instance for this one test
_childContext = new MockApplicationContext(_expectedChildName);
_childContext.MockName = "child";
_childContext.ParentContext = _parentContext;
_grandChildContext.ParentContext = _childContext;
//register contexts in conflict with hierarchical order
ContextRegistry.RegisterContext(_parentContext);
ContextRegistry.RegisterContext(_childContext);
ContextRegistry.RegisterContext(_grandChildContext);
ContextRegistry.RegisterContext(_greatGrandChildContext);
Assert.AreEqual(_expectedParentName, ContextRegistry.GetContext(_expectedParentName).Name);
Assert.AreEqual(_expectedChildName, ContextRegistry.GetContext(_expectedChildName).Name);
Assert.AreEqual(_expectedGrandChildName, ContextRegistry.GetContext(_expectedGrandChildName).Name);
Assert.AreEqual(_expectedGreatGrandChildName, ContextRegistry.GetContext(_expectedGreatGrandChildName).Name);
}
}
}
}