diff --git a/src/Spring/Spring.Core.Configuration/Context/Advice/SpringObjectMethodInterceptor.cs b/src/Spring/Spring.Core.Configuration/Context/Advice/SpringObjectMethodInterceptor.cs
new file mode 100644
index 00000000..d3f3a5f0
--- /dev/null
+++ b/src/Spring/Spring.Core.Configuration/Context/Advice/SpringObjectMethodInterceptor.cs
@@ -0,0 +1,92 @@
+#region License
+
+/*
+ * Copyright © 2002-2008 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#endregion
+
+using System;
+using System.Reflection;
+using AopAlliance.Intercept;
+using Common.Logging;
+using Spring.Objects.Factory.Config;
+using Spring.Context.Attributes;
+
+namespace Spring.Context.Advice
+{
+ ///
+ /// Intercepts calls to methods within the configuration object
+ ///
+ /// Mark Pollack
+ /// Erich Eichinger
+ public class SpringObjectMethodInterceptor : IMethodInterceptor
+ {
+ #region Logging Definition
+
+ private static readonly ILog LOG = LogManager.GetLogger(typeof(SpringObjectMethodInterceptor));
+
+ #endregion
+
+ private readonly IConfigurableListableObjectFactory _configurableListableObjectFactory;
+
+
+ public SpringObjectMethodInterceptor(IConfigurableListableObjectFactory configurableListableObjectFactory)
+ {
+ _configurableListableObjectFactory = configurableListableObjectFactory;
+
+ }
+
+ #region IMethodInterceptor Members
+
+ public object Invoke(IMethodInvocation invocation)
+ {
+ MethodInfo m = invocation.Method;
+ if (m.Name.StartsWith("set_") || m.Name.StartsWith("get_"))
+ return invocation.Proceed();
+
+ string name = m.Name;
+
+ object[] attribs = m.GetCustomAttributes(typeof(DefinitionAttribute), true);
+ if (attribs.Length > 0)
+ {
+
+ }
+
+
+ if (IsCurrentlyInCreation(name))
+ {
+ if (LOG.IsDebugEnabled)
+ {
+ LOG.Debug(name + " currently in creation, created one.");
+ }
+ return invocation.Proceed();
+ }
+ if (LOG.IsDebugEnabled)
+ {
+ LOG.Debug(name + " not in creation, asked the application context for one");
+ }
+
+ return _configurableListableObjectFactory.GetObject(name);
+ }
+
+ private bool IsCurrentlyInCreation(string name)
+ {
+ return _configurableListableObjectFactory.IsCurrentlyInCreation(name);
+ }
+
+ #endregion
+ }
+}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs
index 14a7aa78..36d629e0 100644
--- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs
+++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs
@@ -85,7 +85,8 @@ namespace Spring.Context.Attributes
public void Validate(IProblemReporter problemReporter)
{
- if (Attribute.GetCustomAttribute(ConfigurationClass.GetType(), typeof(ConfigurationAttribute)) != null)
+ //TODO: shouldn't this be "if method has Definition attribute" instead of "if class has Configuration attribute" --????
+ if (Attribute.GetCustomAttribute(ConfigurationClass.ConfigurationClassType, typeof(ConfigurationAttribute)) != null)
{
if (!MethodMetadata.IsVirtual)
{
@@ -113,7 +114,7 @@ namespace Spring.Context.Attributes
private class NonVirtualMethodError : Problem
{
public NonVirtualMethodError(string methodName, Location location)
- : base(String.Format("Method '{0}' must not be private, final or static; change the method's modifiers to continue",
+ : base(String.Format("Method '{0}' must be public virtual; change the method's modifiers to continue",
methodName), location)
{ }
}
diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs
index e50b5a3e..21fd0423 100644
--- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs
+++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs
@@ -7,6 +7,7 @@ using Spring.Collections.Generic;
using System.Reflection;
using Spring.Objects.Factory.Config;
using Common.Logging;
+using Spring.Objects;
namespace Spring.Context.Attributes
{
@@ -90,9 +91,14 @@ namespace Spring.Context.Attributes
RootObjectDefinition objDef = new ConfigurationClassObjectDefinition();
//beanDef.Resource = configClass.Resource;
//beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
+
+ // ???? if we don't do this here, how is the type supposed to be set?
+ //objDef.ObjectType = metadata.ReturnType;
+
objDef.FactoryObjectName = configClass.ObjectName;
objDef.FactoryMethodName = metadata.Name;
objDef.AutowireMode = Objects.Factory.Config.AutoWiringMode.Constructor;
+
//beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
// consider name and any aliases
@@ -214,6 +220,7 @@ namespace Spring.Context.Attributes
private class ConfigurationClassObjectDefinition : RootObjectDefinition
{
+
}
}
diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs
index f21fb73d..a1e425cc 100644
--- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs
+++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs
@@ -8,6 +8,10 @@ using Spring.Objects.Factory.Config;
using Spring.Collections.Generic;
using Spring.Objects.Factory;
using Spring.Core;
+using Spring.Aop.Framework;
+using Spring.Context.Advice;
+using Spring.Aop.Framework.DynamicProxy;
+using Spring.Aop;
namespace Spring.Context.Attributes
{
@@ -21,13 +25,16 @@ namespace Spring.Context.Attributes
private IProblemReporter _problemReporter = new FailFastProblemReporter();
+ public int Order
+ {
+ get { return int.MinValue; }
+ }
+
public IProblemReporter ProblemReporter
{
set { _problemReporter = (value ?? new FailFastProblemReporter()); }
}
-
-
public void PostProcessObjectDefinitionRegistry(IObjectDefinitionRegistry registry)
{
if (_postProcessObjectDefinitionRegistryCalled)
@@ -42,46 +49,6 @@ namespace Spring.Context.Attributes
ProcessConfigObjectDefinitions(registry);
}
-
- private Type GenerateProxyType(Type objectType)
- {
- /*
- ProxyFactory proxyFactory = new ProxyFactory();
- proxyFactory.ProxyTargetAttributes = true;
- proxyFactory.Interfaces = Type.EmptyTypes;
- proxyFactory.TargetSource = new ObjectFactoryTargetSource(originalBeanName, owningObjectFactory);
- SpringObjectMethodInterceptor methodInterceptor = new SpringObjectMethodInterceptor(owningObjectFactory, objectNamingStrategy);
- proxyFactory.AddAdvice(methodInterceptor);
-
- //TODO check type of object isn't infrastructure type.
-
- InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(proxyFactory);
- //iaptb.ProxyDeclaredMembersOnly = true; // make configurable.
- Type type = iaptb.BuildProxyType();
- */
-
- return null;
- }
- private void EnhanceConfigurationClasses(IConfigurableListableObjectFactory objectFactory)
- {
- string[] objectNames = objectFactory.GetObjectDefinitionNames();
-
- for (int i = 0; i < objectNames.Length; i++)
- {
- IObjectDefinition objDef = objectFactory.GetObjectDefinition(objectNames[i]);
- if (Attribute.GetCustomAttribute(objDef.ObjectType, typeof(ConfigurationAttribute)) != null)
- {
- //configNames.Add(objectNames[i]);
-
- //ObjectType is READONLY :(
- //objDef.ObjectType = GenerateProxyType(objDef.ObjectType);
- }
- }
-
-
-
-
- }
public void PostProcessObjectFactory(IConfigurableListableObjectFactory objectFactory)
{
if (_postProcessObjectFactoryCalled)
@@ -96,10 +63,60 @@ namespace Spring.Context.Attributes
// Simply call processConfigBeanDefinitions lazily at this point then.
ProcessConfigObjectDefinitions((IObjectDefinitionRegistry)objectFactory);
}
-
+
EnhanceConfigurationClasses(objectFactory);
}
+ private void EnhanceConfigurationClasses(IConfigurableListableObjectFactory objectFactory)
+ {
+ string[] objectNames = objectFactory.GetObjectDefinitionNames();
+
+ for (int i = 0; i < objectNames.Length; i++)
+ {
+ IObjectDefinition objDef = objectFactory.GetObjectDefinition(objectNames[i]);
+
+ if (((AbstractObjectDefinition)objDef).HasObjectType)
+ {
+ if (Attribute.GetCustomAttribute(objDef.ObjectType, typeof(ConfigurationAttribute)) != null)
+ {
+
+ ProxyFactory proxyFactory = new ProxyFactory();
+ proxyFactory.ProxyTargetAttributes = true;
+ proxyFactory.Interfaces = Type.EmptyTypes;
+ proxyFactory.TargetSource = new ObjectFactoryTargetSource(objectNames[i], objectFactory);
+ SpringObjectMethodInterceptor methodInterceptor = new SpringObjectMethodInterceptor(objectFactory);
+ proxyFactory.AddAdvice(methodInterceptor);
+
+ //TODO check type of object isn't infrastructure type.
+
+ InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(proxyFactory);
+ //iaptb.ProxyDeclaredMembersOnly = true; // make configurable.
+ ((IConfigurableObjectDefinition)objDef).ObjectType = iaptb.BuildProxyType();
+
+ objDef.ConstructorArgumentValues.AddIndexedArgumentValue(objDef.ConstructorArgumentValues.ArgumentCount, proxyFactory);
+
+ }
+ }
+
+ }
+
+ }
+
+ private Type GenerateProxyType(string objectName, IConfigurableListableObjectFactory objectFactory)
+ {
+ ProxyFactory proxyFactory = new ProxyFactory();
+ proxyFactory.ProxyTargetAttributes = true;
+ proxyFactory.Interfaces = Type.EmptyTypes;
+ proxyFactory.TargetSource = new ObjectFactoryTargetSource(objectName, objectFactory);
+ SpringObjectMethodInterceptor methodInterceptor = new SpringObjectMethodInterceptor(objectFactory);
+ proxyFactory.AddAdvice(methodInterceptor);
+
+ //TODO check type of object isn't infrastructure type.
+
+ InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(proxyFactory);
+ //iaptb.ProxyDeclaredMembersOnly = true; // make configurable.
+ return iaptb.BuildProxyType();
+ }
private void ProcessConfigObjectDefinitions(IObjectDefinitionRegistry registry)
{
@@ -143,10 +160,39 @@ namespace Spring.Context.Attributes
reader.LoadObjectDefinitions(parser.ConfigurationClasses);
}
-
- public int Order
+ public class ObjectFactoryTargetSource : ITargetSource
{
- get { return int.MinValue; }
+ private readonly string _objectName;
+ private readonly IConfigurableListableObjectFactory _objectFactory;
+
+ public ObjectFactoryTargetSource(string objectName, IConfigurableListableObjectFactory objectFactory)
+ {
+ _objectName = objectName;
+ _objectFactory = objectFactory;
+ }
+
+ #region ITargetSource Members
+
+ public object GetTarget()
+ {
+ return _objectFactory.GetObject(_objectName);
+ }
+
+ public bool IsStatic
+ {
+ get { return _objectFactory.IsSingleton(_objectName); }
+ }
+
+ public void ReleaseTarget(object target)
+ {
+ }
+
+ public Type TargetType
+ {
+ get { return _objectFactory.GetType(_objectName); }
+ }
+
+ #endregion
}
}
}
diff --git a/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj b/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj
index 62e04478..b5a72565 100644
--- a/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj
+++ b/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj
@@ -39,6 +39,7 @@
+
diff --git a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
index ce8e612b..1f8dbc4d 100644
--- a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
+++ b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
@@ -406,7 +406,7 @@ namespace Spring.Context.Support
if (exceptions.HasExceptions)
{
Delegate target = ContextEvent.GetInvocationList()[0];
- Exception exception = (Exception) exceptions[target];
+ Exception exception = (Exception)exceptions[target];
throw new ApplicationContextException(string.Format("An unhandled exception occured during processing application event {0} in handler {1}", e.GetType(), target.Method), exception);
}
}
@@ -487,33 +487,92 @@ namespace Spring.Context.Support
///
///
/// In the case of errors.
- private void InvokeObjectFactoryPostProcessors()
+ private void InvokeObjectFactoryPostProcessors(IConfigurableListableObjectFactory objectFactory)
{
- // Do NOT include IFactoryObjects; they (typically) need to be instantiated
- // to determine the Type of object that they create, and if they are instantiated
- // then we won't be able to do any factory post processin' on 'em...
- ArrayList factoryProcessorNames = new ArrayList();
- string[] names = GetObjectNamesForType(typeof (IObjectFactoryPostProcessor), true, false);
- foreach (string s in names)
+ // Invoke BeanDefinitionRegistryPostProcessors first, if any.
+ ArrayList processedObjects = new ArrayList();
+
+ if (objectFactory is IObjectDefinitionRegistry)
{
- factoryProcessorNames.Add(s);
+ IObjectDefinitionRegistry registry = (IObjectDefinitionRegistry)objectFactory;
+ ArrayList regularPostProcessors = new ArrayList();
+ ArrayList registryPostProcessors = new ArrayList();
+
+ foreach (IObjectFactoryPostProcessor factoryProcessor in ObjectFactoryPostProcessors)
+ {
+ if (factoryProcessor is IObjectDefinitionRegistryPostProcessor)
+ {
+ ((IObjectDefinitionRegistryPostProcessor)factoryProcessor).PostProcessObjectDefinitionRegistry(registry);
+ registryPostProcessors.Add(factoryProcessor);
+ }
+ else
+ {
+ regularPostProcessors.Add(factoryProcessor);
+ }
+ }
+
+ IDictionary objectMap = objectFactory.GetObjectsOfType(typeof(IObjectDefinitionRegistryPostProcessor), true, false);
+
+ ArrayList registryPostProcessorObjects = new ArrayList(objectMap.Values);
+ registryPostProcessorObjects.Sort(new OrderComparator());
+
+ foreach (System.Object processor in registryPostProcessorObjects)
+ {
+ ((IObjectDefinitionRegistryPostProcessor)processor).PostProcessObjectDefinitionRegistry(registry);
+ }
+
+ InvokeObjectFactoryPostProcessors(registryPostProcessors, objectFactory);
+ InvokeObjectFactoryPostProcessors(registryPostProcessorObjects, objectFactory);
+ InvokeObjectFactoryPostProcessors(regularPostProcessors, objectFactory);
+
+ // processedObjects.Add(objectMap.Keys);
+
+ foreach (DictionaryEntry entry in objectMap)
+ {
+ processedObjects.Add(entry.Key);
+ }
+
}
-
+ else
+ {
+ foreach (IObjectFactoryPostProcessor factoryProcessor in ObjectFactoryPostProcessors)
+ {
+ // Invoke factory processors registered with the context instance.
+ factoryProcessor.PostProcessObjectFactory(objectFactory);
+ }
+ }
+
+ // Do not initialize FactoryBeans here: We need to leave all regular beans
+ // uninitialized to let the bean factory post-processors apply to them!
+ ArrayList factoryProcessorNames = new ArrayList();
+ string[] names = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false);
+ foreach (string name in names)
+ {
+ factoryProcessorNames.Add(name);
+ }
+
+ // Separate between ObjectFactoryPostProcessors that implement PriorityOrdered,
+ // Ordered, and the rest.
ArrayList priorityOrderedFactoryProcessors = new ArrayList();
ArrayList orderedFactoryProcessorsNames = new ArrayList();
ArrayList nonOrderedFactoryProcessorNames = new ArrayList();
-
+
for (int i = 0; i < factoryProcessorNames.Count; ++i)
{
- string processorName = (string) factoryProcessorNames[i];
- if (IsTypeMatch(processorName, typeof(IPriorityOrdered)))
+ string processorName = (string)factoryProcessorNames[i];
+ if (processedObjects.Contains(processorName))
+ {
+ //skip -- already processed in first phase above
+ Debug.WriteLine("");
+ }
+ else if (IsTypeMatch(processorName, typeof(IPriorityOrdered)))
{
priorityOrderedFactoryProcessors.Add(ObjectFactory.GetObject(processorName, typeof(IObjectFactoryPostProcessor)));
}
else if (IsTypeMatch(processorName, typeof(IOrdered)))
{
orderedFactoryProcessorsNames.Add(processorName);
- }
+ }
else
{
nonOrderedFactoryProcessorNames.Add(processorName);
@@ -527,17 +586,17 @@ namespace Spring.Context.Support
foreach (string orderedFactoryProcessorsName in orderedFactoryProcessorsNames)
{
orderedFactoryProcessors.Add(ObjectFactory.GetObject(orderedFactoryProcessorsName,
- typeof (IObjectFactoryPostProcessor)));
+ typeof(IObjectFactoryPostProcessor)));
}
orderedFactoryProcessors.Sort(new OrderComparator());
InvokeObjectFactoryPostProcessors(orderedFactoryProcessors, ObjectFactory);
-
+
// and then the unordered ones...
ArrayList nonOrderedPostProcessors = new ArrayList();
foreach (string nonOrderedFactoryProcessorName in nonOrderedFactoryProcessorNames)
{
nonOrderedPostProcessors.Add(ObjectFactory.GetObject(nonOrderedFactoryProcessorName,
- typeof (IObjectFactoryPostProcessor)));
+ typeof(IObjectFactoryPostProcessor)));
}
InvokeObjectFactoryPostProcessors(nonOrderedPostProcessors, ObjectFactory);
@@ -563,7 +622,7 @@ namespace Spring.Context.Support
// Now will find any additional IObjectFactoryPostProcessors that implement IPriorityOrdered that may have been
// resolved due to using TypeAlias
string[] factoryProcessorNamesAfterTypeAlias = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false);
- priorityOrderedFactoryProcessors.Clear();
+ priorityOrderedFactoryProcessors.Clear();
foreach (string factoryProcessorName in factoryProcessorNamesAfterTypeAlias)
{
if (!factoryProcessorNames.Contains(factoryProcessorName))
@@ -912,10 +971,7 @@ namespace Spring.Context.Support
#endregion
- foreach (IObjectFactoryPostProcessor factoryProcessor in ObjectFactoryPostProcessors)
- {
- factoryProcessor.PostProcessObjectFactory(objectFactory);
- }
+
#region Instrumentation
@@ -939,7 +995,7 @@ namespace Spring.Context.Support
#endregion
- InvokeObjectFactoryPostProcessors();
+ InvokeObjectFactoryPostProcessors(objectFactory);
RegisterObjectPostProcessors(objectFactory);
InitEventRegistry();
diff --git a/src/Spring/Spring.Core/Objects/Factory/Parsing/Location.cs b/src/Spring/Spring.Core/Objects/Factory/Parsing/Location.cs
index 48832944..6ca9a321 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Parsing/Location.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Parsing/Location.cs
@@ -18,7 +18,8 @@ namespace Spring.Objects.Factory.Parsing
///
public Location(IResource resource, object source)
{
- AssertUtils.ArgumentNotNull(resource, "resource");
+ //TODO: look into re-enabling this since resource *is* NULL when parsing config classes vs. acquiring IResources
+ //AssertUtils.ArgumentNotNull(resource, "resource");
this.resource = resource;
this.source = source;
}
diff --git a/src/Spring/Spring.Core/Objects/Factory/Parsing/Problem.cs b/src/Spring/Spring.Core/Objects/Factory/Parsing/Problem.cs
index 0848261a..7fa96f46 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Parsing/Problem.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Parsing/Problem.cs
@@ -59,7 +59,7 @@ namespace Spring.Objects.Factory.Parsing
public string ResourceDescription
{
- get { return _location.Resource.Description; }
+ get { return _location.Resource!=null ? _location.Resource.Description : string.Empty; }
}
public override string ToString()
diff --git a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs
index 50351b9b..b01740ff 100644
--- a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs
+++ b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs
@@ -11,67 +11,87 @@ namespace Spring.Context.Annotation
{
private GenericApplicationContext _ctx;
- private ConfigurationClassPostProcessor _postProcessor;
-
[SetUp]
public void _SetUp()
{
_ctx = new GenericApplicationContext();
- var builder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ObjectDefinitions));
+ var builder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
_ctx.RegisterObjectDefinition("whoCares", builder.ObjectDefinition);
- _postProcessor = new ConfigurationClassPostProcessor();
- _postProcessor.PostProcessObjectDefinitionRegistry(_ctx);
+ var b2 = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
+ _ctx.RegisterObjectDefinition("ccpp", b2.ObjectDefinition);
+
+ _ctx.Refresh();
}
[Test]
- public void CanRegisterDefintions()
+ public void Can_Parse_and_Register_Defintions()
{
- Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(3));
+ Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(4));
}
[Test]
- public void CanRetreiveActualObjectsFromContext()
+ public void Can_Retreive_Actual_Objects_From_Context()
{
- Assert.That(_ctx[typeof(Parent).Name], Is.TypeOf());
- Assert.That(_ctx[typeof(Child).Name], Is.TypeOf());
+ Assert.That(_ctx[typeof(SingletonParent).Name], Is.TypeOf());
+ Assert.That(_ctx[typeof(PrototypeChild).Name], Is.TypeOf());
}
[Test]
- public void CanSatisfyDependenciesOfObjects()
+ public void Can_Satisfy_Dependencies_Of_Objects()
{
- Assert.That(((Parent)_ctx[typeof(Parent).Name]).Child, Is.Not.Null);
+ Assert.That(((SingletonParent)_ctx[typeof(SingletonParent).Name]).Child, Is.Not.Null);
+ }
+
+ [Test]
+ public void Can_Respect_Default_Singleton_Scope()
+ {
+ var firstObject = (SingletonParent)_ctx[typeof(SingletonParent).Name];
+ var secondObject = (SingletonParent)_ctx[typeof(SingletonParent).Name];
+
+ Assert.That(firstObject, Is.SameAs(secondObject));
+ }
+
+ [Test]
+ public void Can_Respect_Explicit_PrototypeScope()
+ {
+ var firstObject = (PrototypeChild)_ctx[typeof(PrototypeChild).Name];
+ var secondObject = (PrototypeChild)_ctx[typeof(PrototypeChild).Name];
+
+ Assert.That(firstObject, Is.Not.SameAs(secondObject));
}
}
[Configuration]
- public class ObjectDefinitions
+ public class TheConfigurationClass
{
[Definition]
- public Parent Parent()
+ [Scope(ObjectScope.Prototype)]
+ public virtual PrototypeChild PrototypeChild()
{
- return new Parent(Child());
+ return new PrototypeChild();
}
[Definition]
- public Child Child()
+ public virtual SingletonParent SingletonParent()
{
- return new Child();
+ return new SingletonParent(PrototypeChild());
}
+
}
- public class Parent
+ public class SingletonParent
{
- private Child _child;
+ private PrototypeChild _child;
- public Parent(Child child)
+ public SingletonParent(PrototypeChild child)
{
_child = child;
}
- public Child Child
+ public PrototypeChild Child
{
get
{
@@ -80,5 +100,6 @@ namespace Spring.Context.Annotation
}
}
- public class Child { }
+
+ public class PrototypeChild { }
}