Uploaded image for project: 'Spring.NET'
  1. Spring.NET
  2. SPRNET-1512

Spring.Context.Support.AbstractApplicationContext.GetObjectNamesForType(..) fails to account for parent ApplicationContext/ObjectFactory object definitions

    Details

    • Type: Task
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 2.0 M1
    • Fix Version/s: 2.0 M2
    • Component/s: Spring-NET-CORE
    • Labels:
      None

      Description

      The following test illustrates the problem...

      [TestFixture]
      public class TheTest
      {
      [Test]
      public void Test()

      { var parentObjectDefinition = new RootObjectDefinition(typeof (ObjectInParent)); var childObjectDefinition = new RootObjectDefinition(typeof (ObjectInChild)); var parent = new GenericApplicationContext(); parent.RegisterObjectDefinition("objectInParent", parentObjectDefinition); var child = new GenericApplicationContext(parent); child.RegisterObjectDefinition("objectInChild", childObjectDefinition); parent.Refresh(); child.Refresh(); //parent ctx can resolve just its own registered object Assert.That(parent.GetObject<ObjectInParent>(), Is.Not.Null); Assert.That(parent.GetObject("objectInParent"), Is.Not.Null); //child can resolve its own registered object... Assert.That(child.GetObject<ObjectInChild>(), Is.Not.Null); Assert.That(child.GetObject("objectInChild"), Is.Not.Null); //child can delegate to parent to resolve the parent's object Assert.That(child.GetObject<ObjectInParent>(), Is.Not.Null); // <-- this FAILs Assert.That(child.GetObject("objectInParent"), Is.Not.Null); // <-- this PASSes }

      }

      public class ObjectInParent
      {

      }

      public class ObjectInChild
      {

      }

      The problem with this test is that .GetObject(string name) properly respects parent/child hierarchies of ApplicationContexts/ObjectFactories but the new .GetObject<T>() does not.

      I have tracked this down to the fact that .GetObject<T>() relies upon Spring.Context.Support.AbstractApplicationContext.GetObjectNamesForType(...) which in turn eventually calls Spring.Objects.Factory.Support.DefaultListableObjectFactory.DoGetNamesForType(...) .

      Unfortunately, DefaultListableObjectFactory.DoGetNamesForType(...) only inspects the current ObjectFactory's object definition names and then any manually-registered singletons before it returns all matches. This code-path NEVER bothers to inspect object definitions for any PARENT object factories, which is why our code-path from GetObject<T>() fails to respect the context/factory parent-child hierarchy.

      To fix this will require changing the definition of DefaultListableObjectFactory.GetObjectDefinitionNames() and DefaultListableObjectFactory.GetSingletonNames() to check for a non-null ParentObjectFactory and then 'merge' the names from the non-null Parent with its own. Then in the body of DefaultListableObjectFactory.DoGetNamesForType(...) we will need to change the call to GetMergedObjectDefinitions(...) to pass a true for the second arg instead of false. This would permit GetMergedObjectDefinitions(...) to traverse to parent factory/contexts when it searches for the ROD to return and should solve the problem.

        Attachments

          Activity

            People

            • Assignee:
              sbohlen Steve Bohlen
              Reporter:
              sbohlen Steve Bohlen
            • Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

              • Created:
                Updated:
                Resolved: