container refresh modifications to interact with ConfigurationClassPostProcessor as required
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Intercepts calls to methods within the configuration object
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
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
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
{ }
|
||||
}
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Context\Advice\SpringObjectMethodInterceptor.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClass.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassMethod.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
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <exception cref="ObjectsException">In the case of errors.</exception>
|
||||
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();
|
||||
|
||||
@@ -18,7 +18,8 @@ namespace Spring.Objects.Factory.Parsing
|
||||
/// <param name="source"></param>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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<Parent>());
|
||||
Assert.That(_ctx[typeof(Child).Name], Is.TypeOf<Child>());
|
||||
Assert.That(_ctx[typeof(SingletonParent).Name], Is.TypeOf<SingletonParent>());
|
||||
Assert.That(_ctx[typeof(PrototypeChild).Name], Is.TypeOf<PrototypeChild>());
|
||||
}
|
||||
|
||||
[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 { }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user