From 85af8a1d8fa321d7c66e90d5663a2159b96f413e Mon Sep 17 00:00:00 2001 From: sbohlen Date: Fri, 19 Nov 2010 14:40:12 +0000 Subject: [PATCH] additional tests introduced; minor mods to attribute classes to support better syntax for setting values --- .../Context/Attributes/ConfigurationClass.cs | 4 +- .../Attributes/ConfigurationClassMethod.cs | 4 +- ...onfigurationClassObjectDefinitionReader.cs | 81 +++++----- .../Attributes/ConfigurationClassParser.cs | 10 +- .../ConfigurationClassPostProcessor.cs | 6 +- .../Context/Attributes/DefinitionAttribute.cs | 27 +++- .../Attributes/ImportResourceAttribute.cs | 35 ++++- .../{LazyAttrribute.cs => LazyAttribute.cs} | 14 +- .../Context/Config/ContextNamespaceParser.cs | 46 ++++++ .../Spring.Core.Configuration.2010.csproj | 11 +- .../Spring.Aop.Tests.2010.csproj | 4 +- .../ConfigurationClassPostProcessorTests.cs | 138 ++++++++++++++++-- .../Attributes/DefinitionAttributeTests.cs | 38 +++++ .../ImportResourceAttributeTests.cs | 48 ++++++ .../Context/Attributes/ObjectDefinitions.xml | 5 + ...pring.Core.Configuration.Tests.2010.csproj | 20 ++- 16 files changed, 406 insertions(+), 85 deletions(-) rename src/Spring/Spring.Core.Configuration/Context/Attributes/{LazyAttrribute.cs => LazyAttribute.cs} (82%) create mode 100644 src/Spring/Spring.Core.Configuration/Context/Config/ContextNamespaceParser.cs create mode 100644 test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/DefinitionAttributeTests.cs create mode 100644 test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ImportResourceAttributeTests.cs create mode 100644 test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ObjectDefinitions.xml diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClass.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClass.cs index 8c22c382..3f0cade0 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClass.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClass.cs @@ -96,8 +96,8 @@ namespace Spring.Context.Attributes public void Validate(IProblemReporter problemReporter) { - // An @Bean method may only be overloaded through inheritance. No single - // @Configuration class may declare two @Bean methods with the same name. + // A [Definition] method may only be overloaded through inheritance. No single + // [Configuration] class may declare two [Definition] methods with the same name. char hashDelim = '#'; Dictionary methodNameCounts = new Dictionary(); foreach (ConfigurationClassMethod method in _methods) diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs index 36d629e0..ecb49b02 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassMethod.cs @@ -29,14 +29,14 @@ namespace Spring.Context.Attributes { /** - * Represents a {@link Configuration} class method marked with the {@link Bean} annotation. + * Represents a {@link Configuration} class method marked with the {@link Object} annotation. * * @author Chris Beams * @author Juergen Hoeller * @since 3.0 * @see ConfigurationClass * @see ConfigurationClassParser - * @see ConfigurationClassBeanDefinitionReader + * @see ConfigurationClassObjectDefinitionReader */ public class ConfigurationClassMethod diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs index 21fd0423..df7517b5 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassObjectDefinitionReader.cs @@ -8,6 +8,7 @@ using System.Reflection; using Spring.Objects.Factory.Config; using Common.Logging; using Spring.Objects; +using Spring.Util; namespace Spring.Context.Attributes { @@ -52,17 +53,17 @@ namespace Spring.Context.Attributes { if (configClass.ObjectName != null) { - // a bean definition already exists for this configuration class -> nothing to do + // a Object definition already exists for this configuration class -> nothing to do return; } - // no bean definition exists yet -> this must be an imported configuration class (@Import). - GenericObjectDefinition configBeanDef = new GenericObjectDefinition(); + // no Object definition exists yet -> this must be an imported configuration class (@Import). + GenericObjectDefinition configObjectDef = new GenericObjectDefinition(); String className = configClass.ConfigurationClassType.Name; - configBeanDef.ObjectType = configClass.GetType(); + configObjectDef.ObjectType = configClass.ConfigurationClassType; if (CheckConfigurationClassCandidate(configClass.ConfigurationClassType)) { - String configObjectName = ObjectDefinitionReaderUtils.RegisterWithGeneratedName(configBeanDef, _registry); + String configObjectName = ObjectDefinitionReaderUtils.RegisterWithGeneratedName(configObjectDef, _registry); configClass.ObjectName = configObjectName; if (_logger.IsDebugEnabled) { @@ -89,34 +90,38 @@ namespace Spring.Context.Attributes MethodInfo metadata = method.MethodMetadata; 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; - + //ObjectDef.Resource = configClass.Resource; + //ObjectDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource())); + + + objDef.FactoryObjectName = configClass.ObjectName; objDef.FactoryMethodName = metadata.Name; objDef.AutowireMode = Objects.Factory.Config.AutoWiringMode.Constructor; - - //beanDef.setAttribute(RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); + + //ObjectDef.setAttribute(RequiredAnnotationObjectPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE); // consider name and any aliases - //Dictionary beanAttributes = metadata.getAnnotationAttributes(Bean.class.getName()); + //Dictionary ObjectAttributes = metadata.getAnnotationAttributes(Object.class.getName()); object[] objectAttributes = metadata.GetCustomAttributes(typeof(DefinitionAttribute), true); List names = new List(); for (int i = 0; i < objectAttributes.Length; i++) { - string[] namesAndAliases = ((DefinitionAttribute)objectAttributes[i]).Name; + string[] namesAndAliases = ((DefinitionAttribute)objectAttributes[i]).NamesToArray; - if (namesAndAliases == null) + if (namesAndAliases != null) + { + names.Add(metadata.Name); + } + else + { namesAndAliases = new[] { metadata.Name }; + } - for (int j = 0; j > namesAndAliases.Length; j++) + for (int j = 0; j < namesAndAliases.Length; j++) { names.Add(namesAndAliases[j]); } - } string objectName = (names.Count > 0 ? names[0] : method.MethodMetadata.Name); @@ -128,15 +133,15 @@ namespace Spring.Context.Attributes // has this already been overridden (e.g. via XML)? if (_registry.ContainsObjectDefinition(objectName)) { - IObjectDefinition existingBeanDef = _registry.GetObjectDefinition(objectName); - // is the existing bean definition one that was created from a configuration class? - if (!(existingBeanDef is ConfigurationClassObjectDefinition)) + IObjectDefinition existingObjectDef = _registry.GetObjectDefinition(objectName); + // is the existing Object definition one that was created from a configuration class? + if (!(existingObjectDef is ConfigurationClassObjectDefinition)) { // no -> then it's an external override, probably XML // overriding is legal, return immediately if (_logger.IsDebugEnabled) { - _logger.Debug(String.Format("Skipping loading bean definition for {0}: a definition for object " + + _logger.Debug(String.Format("Skipping loading Object definition for {0}: a definition for object " + "'{1}' already exists. This is likely due to an override in XML.", method, objectName)); } return; @@ -146,13 +151,13 @@ namespace Spring.Context.Attributes if (Attribute.GetCustomAttribute(metadata, typeof(PrimaryAttribute)) != null) { //TODO: determine how to respond to this attribute's presence - //beanDef.isPrimary = true; + //ObjectDef.isPrimary = true; } - // is this bean to be instantiated lazily? - if (Attribute.GetCustomAttribute(metadata, typeof(LazyAttrribute)) != null) + // is this Object to be instantiated lazily? + if (Attribute.GetCustomAttribute(metadata, typeof(LazyAttribute)) != null) { - objDef.IsLazyInit = (Attribute.GetCustomAttribute(metadata, typeof(LazyAttrribute)) as LazyAttrribute).LazyInitialize; + objDef.IsLazyInit = (Attribute.GetCustomAttribute(metadata, typeof(LazyAttribute)) as LazyAttribute).LazyInitialize; } if (Attribute.GetCustomAttribute(metadata, typeof(DependsOnAttribute)) != null) @@ -160,20 +165,16 @@ namespace Spring.Context.Attributes objDef.DependsOn = (Attribute.GetCustomAttribute(metadata, typeof(DependsOnAttribute)) as DependsOnAttribute).Name; } - //Autowire autowire = (Autowire) beanAttributes.get("autowire"); + //Autowire autowire = (Autowire) ObjectAttributes.get("autowire"); //if (autowire.isAutowire()) { - // beanDef.setAutowireMode(autowire.value()); + // ObjectDef.setAutowireMode(autowire.value()); //} - //String initMethodName = (String) beanAttributes.get("initMethod"); - //if (StringUtils.hasText(initMethodName)) { - // beanDef.setInitMethodName(initMethodName); - //} - - //String destroyMethodName = (String) beanAttributes.get("destroyMethod"); - //if (StringUtils.hasText(destroyMethodName)) { - // beanDef.setDestroyMethodName(destroyMethodName); - //} + if (Attribute.GetCustomAttribute(metadata, typeof(DefinitionAttribute)) != null) + { + objDef.InitMethodName = (Attribute.GetCustomAttribute(metadata, typeof(DefinitionAttribute)) as DefinitionAttribute).InitMethod; + objDef.DestroyMethodName = (Attribute.GetCustomAttribute(metadata, typeof(DefinitionAttribute)) as DefinitionAttribute).DestroyMethod; + } // consider scoping if (Attribute.GetCustomAttribute(metadata, typeof(ScopeAttribute)) != null) @@ -183,7 +184,7 @@ namespace Spring.Context.Attributes if (_logger.IsDebugEnabled) { - _logger.Debug(String.Format("Registering bean definition for [Definition] method {0}.{1}()", configClass.ConfigurationClassType.Name, objectName)); + _logger.Debug(String.Format("Registering Object definition for [Definition] method {0}.{1}()", configClass.ConfigurationClassType.Name, objectName)); } _registry.RegisterObjectDefinition(objectName, objDef); @@ -201,8 +202,8 @@ namespace Spring.Context.Attributes { try { - IObjectDefinitionReader readerInstance = - (IObjectDefinitionReader)Activator.CreateInstance(readerClass.GetType(), _registry); + IObjectDefinitionReader readerInstance = + (IObjectDefinitionReader)Activator.CreateInstance(readerClass, _registry); readerInstanceCache.Add(readerClass, readerInstance); } diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassParser.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassParser.cs index 04c907f4..c6091d96 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassParser.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassParser.cs @@ -31,9 +31,9 @@ namespace Spring.Context.Attributes get { return _configurationClasses; } } - //public void Parse(String className, String beanName) + //public void Parse(String className, String ObjectName) //{ - // ProcessConfigurationClass(new ConfigurationClass(className, beanName)); + // ProcessConfigurationClass(new ConfigurationClass(className, ObjectName)); //} public void Parse(Type type, string objectName) @@ -66,17 +66,17 @@ namespace Spring.Context.Attributes { if (Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportAttribute)) != null) { - ImportAttribute attrib = Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType.GetType(), typeof(ImportAttribute)) as ImportAttribute; + ImportAttribute attrib = Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportAttribute)) as ImportAttribute; ProcessImport(configurationClass, attrib.Types); } if (Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportResourceAttribute)) != null) { - ImportResourceAttribute attrib = Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType.GetType(), typeof(ImportResourceAttribute)) as ImportResourceAttribute; + ImportResourceAttribute attrib = Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportResourceAttribute)) as ImportResourceAttribute; foreach (string resource in attrib.Resources) { - configurationClass.AddImportedResource(resource, attrib.DefinitionReader.GetType()); + configurationClass.AddImportedResource(resource, attrib.DefinitionReader); } } diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs index a1e425cc..54210c4a 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ConfigurationClassPostProcessor.cs @@ -59,8 +59,8 @@ namespace Spring.Context.Attributes _postProcessObjectFactoryCalled = true; if (!_postProcessObjectDefinitionRegistryCalled) { - // BeanDefinitionRegistryPostProcessor hook apparently not supported... - // Simply call processConfigBeanDefinitions lazily at this point then. + // ObjectDefinitionRegistryPostProcessor hook apparently not supported... + // Simply call processConfigObjectDefinitions lazily at this point then. ProcessConfigObjectDefinitions((IObjectDefinitionRegistry)objectFactory); } @@ -155,7 +155,7 @@ namespace Spring.Context.Attributes } parser.Validate(); - // Read the model and create bean definitions based on its content + // Read the model and create Object definitions based on its content ConfigurationClassObjectDefinitionReader reader = new ConfigurationClassObjectDefinitionReader(registry, _problemReporter); reader.LoadObjectDefinitions(parser.ConfigurationClasses); } diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/DefinitionAttribute.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/DefinitionAttribute.cs index 39efce04..93086cec 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/DefinitionAttribute.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/DefinitionAttribute.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Text; using Spring.Objects.Factory.Config; +using Spring.Util; namespace Spring.Context.Attributes { @@ -10,9 +11,11 @@ namespace Spring.Context.Attributes { private AutoWiringMode _autoWire = AutoWiringMode.No; + private string _destroyMethod; + private string _initMethod; - private string[] _name; + private string _names; /// /// Are dependencies to be injected via autowiring? @@ -26,9 +29,9 @@ namespace Spring.Context.Attributes _autoWire = value; } } - private string _destroyMethod; + /// - /// The optional name of a method to call on the bean instance upon closing the + /// The optional name of a method to call on the Object instance upon closing the /// application context, for example a Close() method on a DataSource. /// The method must have no arguments but may throw any exception. /// @@ -47,11 +50,11 @@ namespace Spring.Context.Attributes _destroyMethod = value; } } - + /// /// The optional name of a method to call on the object instance during initialization. /// Not commonly used, given that the method may be called programmatically directly - /// within the body of a Bean-annotated method. + /// within the body of a Object-annotated method. /// /// The init method. public string InitMethod @@ -69,15 +72,23 @@ namespace Spring.Context.Attributes /// name is ignored. /// /// The name. - public string[] Name + public string Names { get { - return _name; + return _names; } set { - _name = value; + _names = value; + } + } + + public string[] NamesToArray + { + get + { + return StringUtils.DelimitedListToStringArray(_names, ","); } } diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/ImportResourceAttribute.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/ImportResourceAttribute.cs index 83fdc689..241ace48 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/ImportResourceAttribute.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/ImportResourceAttribute.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Text; using Spring.Objects.Factory.Support; using Spring.Objects.Factory.Xml; +using Spring.Util; namespace Spring.Context.Attributes { @@ -12,31 +13,51 @@ namespace Spring.Context.Attributes [AttributeUsage(AttributeTargets.Class)] public class ImportResourceAttribute : Attribute { - private IObjectDefinitionReader _objectDefinitionReader; + private Type _objectDefinitionReader = typeof(XmlObjectDefinitionReader); private string[] _resources; /// - /// Initializes a new instance of the ImportResource class. + /// Initializes a new instance of the ImportResourceAttribute class. /// - /// /// - public ImportResourceAttribute(IObjectDefinitionReader objectDefinitionReader, string[] resources) + public ImportResourceAttribute(string[] resources) { - _objectDefinitionReader = objectDefinitionReader; + if (resources ==null || resources.Length ==0) + throw new ArgumentException("resources cannot be null or empty!"); + _resources = resources; } + + /// + /// Initializes a new instance of the ImportResourceAttribute class. + /// + /// + public ImportResourceAttribute(string resource) + { + if (StringUtils.IsNullOrEmpty(resource)) + throw new ArgumentException("resource cannot be null or empty!"); + + _resources = new[] { resource }; + } + /// /// implementation to use when processing resources specified /// by the attribute. /// /// The . - public IObjectDefinitionReader DefinitionReader + public Type DefinitionReader { - get { return _objectDefinitionReader; } + get + { + return _objectDefinitionReader; + } set { + if (!((typeof(IObjectDefinitionReader).IsAssignableFrom(value)))) + throw new ArgumentException(string.Format("DefinitionReader must be of type IObjectDefinitionReader but was of type {0}", value.Name)); + _objectDefinitionReader = value; } } diff --git a/src/Spring/Spring.Core.Configuration/Context/Attributes/LazyAttrribute.cs b/src/Spring/Spring.Core.Configuration/Context/Attributes/LazyAttribute.cs similarity index 82% rename from src/Spring/Spring.Core.Configuration/Context/Attributes/LazyAttrribute.cs rename to src/Spring/Spring.Core.Configuration/Context/Attributes/LazyAttribute.cs index 99ba99b1..229f4d72 100644 --- a/src/Spring/Spring.Core.Configuration/Context/Attributes/LazyAttrribute.cs +++ b/src/Spring/Spring.Core.Configuration/Context/Attributes/LazyAttribute.cs @@ -23,19 +23,27 @@ namespace Spring.Context.Attributes /// /// [AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)] - public class LazyAttrribute : Attribute + public class LazyAttribute : Attribute { private bool _lazyInitialize = true; /// - /// Initializes a new instance of the Lazy class. + /// Initializes a new instance of the LazyAttribute class. /// /// - public LazyAttrribute(bool lazyInitialize) + public LazyAttribute(bool lazyInitialize) { _lazyInitialize = lazyInitialize; } + /// + /// Initializes a new instance of the LazyAttribute class. + /// + public LazyAttribute() + { + + } + /// /// Whether lazy initialization should occur. /// diff --git a/src/Spring/Spring.Core.Configuration/Context/Config/ContextNamespaceParser.cs b/src/Spring/Spring.Core.Configuration/Context/Config/ContextNamespaceParser.cs new file mode 100644 index 00000000..d385c84a --- /dev/null +++ b/src/Spring/Spring.Core.Configuration/Context/Config/ContextNamespaceParser.cs @@ -0,0 +1,46 @@ +using System; +using System.Collections.Generic; +using System.Text; +using Spring.Objects.Factory.Xml; + +namespace Spring.Context.Config +{ + /// + /// NamespaceParser allowing for the configuration of + /// declarative transaction management using either XML or using attributes. + /// + /// This namespace handler is the central piece of functionality in the + /// Spring transaction management facilities and offers two appraoches + /// to declaratively manage transactions. + /// + /// One approach uses transaction semantics defined in XML using the + /// <tx:advice> elements, the other uses attributes + /// in combination with the <tx:annotation-driven> element. + /// Both approached are detailed in the Spring reference manual. + /// + [ + NamespaceParser( + Namespace = "http://www.springframework.net/context", + SchemaLocationAssemblyHint = typeof(ContextNamespaceParser), + SchemaLocation = "/Spring.Context.Config/spring-context-1.3.xsd" + ) + ] + public class ContextNamespaceParser : NamespaceParserSupport + { + + + /// + /// Register the for the 'advice' and + /// 'attribute-driven' tags. + /// + public override void Init() + { + + + RegisterObjectDefinitionParser("attribute-config", new AttributeConfigObjectDefinitionParser()); + + //RegisterObjectDefinitionParser("component-scan", new ComponentScanObjectDefinitionParser()); + + } + } +} 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 b5a72565..422d636c 100644 --- a/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj +++ b/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj @@ -50,12 +50,19 @@ - + + + + - + + + Designer + + {3A3A4E65-45A6-4B20-B460-0BEDC302C02C} diff --git a/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj b/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj index e697c97d..6f8972ab 100644 --- a/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj +++ b/test/Spring/Spring.Aop.Tests/Spring.Aop.Tests.2010.csproj @@ -277,7 +277,9 @@ - + + Designer + 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 b01740ff..d1894cf7 100644 --- a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs +++ b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs @@ -3,8 +3,10 @@ using NUnit.Framework; using Spring.Context.Support; using Spring.Objects.Factory.Support; using Spring.Context.Attributes; +using Spring.Objects.Factory.Config; +using Spring.Objects.Factory.Xml; -namespace Spring.Context.Annotation +namespace Spring.Context.Attributes { [TestFixture] public class ConfigurationClassPostProcessorTests @@ -17,31 +19,46 @@ namespace Spring.Context.Annotation _ctx = new GenericApplicationContext(); var builder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass)); - _ctx.RegisterObjectDefinition("whoCares", builder.ObjectDefinition); + _ctx.RegisterObjectDefinition("theConfigClass", builder.ObjectDefinition); var b2 = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor)); - _ctx.RegisterObjectDefinition("ccpp", b2.ObjectDefinition); + _ctx.RegisterObjectDefinition("thePostProcessor", b2.ObjectDefinition); + + Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(2)); _ctx.Refresh(); } [Test] - public void Can_Parse_and_Register_Defintions() + public void Can_Assign_Init_And_Destroy_Methods() { - Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(4)); + IObjectDefinition def = _ctx.GetObjectDefinition(typeof(ObjectWithInitAndDestroyMethods).Name); + + Assert.That(def, Is.Not.Null); + Assert.That(def.InitMethodName, Is.EqualTo("CallToInit")); + Assert.That(def.DestroyMethodName, Is.EqualTo("CallToDestroy")); } [Test] - public void Can_Retreive_Actual_Objects_From_Context() + public void Can_Import_Configurations_From_Additional_Classes() { - Assert.That(_ctx[typeof(SingletonParent).Name], Is.TypeOf()); - Assert.That(_ctx[typeof(PrototypeChild).Name], Is.TypeOf()); + Assert.That(_ctx.GetObject(typeof(AnImportedType).Name), Is.Not.Null); } [Test] - public void Can_Satisfy_Dependencies_Of_Objects() + public void Can_Respect_Assigned_Aliases() { - Assert.That(((SingletonParent)_ctx[typeof(SingletonParent).Name]).Child, Is.Not.Null); + var firstObject = _ctx["TheFirstAlias"]; + var secondObject = _ctx["TheSecondAlias"]; + Assert.That(firstObject, Is.InstanceOf()); + Assert.That(secondObject, Is.InstanceOf()); + } + + [Test] + public void Can_Respect_Assigned_Name() + { + var result = _ctx["TheName"]; + Assert.That(result, Is.InstanceOf()); } [Test] @@ -62,11 +79,77 @@ namespace Spring.Context.Annotation Assert.That(firstObject, Is.Not.SameAs(secondObject)); } + [Test] + public void Can_Respect_Lazy_Attribute() + { + Assert.That(_ctx.GetObjectDefinition(typeof(ImplicitLazyInitObject).Name).IsLazyInit, Is.True); + Assert.That(_ctx.GetObjectDefinition(typeof(ExplicitLazyInitObject).Name).IsLazyInit, Is.True); + Assert.That(_ctx.GetObjectDefinition(typeof(ExplicitNonLazyInitObject).Name).IsLazyInit, Is.False); + } + + [Test] + public void Can_Retreive_Actual_Objects_From_Context() + { + Assert.That(_ctx[typeof(SingletonParent).Name], Is.TypeOf()); + Assert.That(_ctx[typeof(PrototypeChild).Name], Is.TypeOf()); + } + + [Test] + public void Can_Satisfy_Dependencies_Of_Objects() + { + Assert.That(((SingletonParent)_ctx[typeof(SingletonParent).Name]).Child, Is.Not.Null); + } + + + [Test] + public void Can_Respect_Imported_Resources() + { + Assert.That(_ctx["xmlRegisteredObject"], Is.Not.Null); + } + } + + public class ObjectWithInitAndDestroyMethods + { + public void CallToDestroy() { } + public void CallToInit() { } + } + + + + + [Configuration] + [ImportResource("assembly://Spring.Core.Configuration.Tests/Spring.Context.Attributes/ObjectDefinitions.xml", DefinitionReader = typeof(XmlObjectDefinitionReader))] + public class TheImportedConfigurationClass + { + [Definition] + public virtual AnImportedType AnImportedType() + { + return new AnImportedType(); + } } [Configuration] + [Import(new Type[] { typeof(TheImportedConfigurationClass) })] public class TheConfigurationClass { + [Definition(Names = "TheName")] + public virtual SingleNamedObject NamedObject() + { + return new SingleNamedObject(); + } + + [Definition(DestroyMethod = "CallToDestroy", InitMethod = "CallToInit")] + public virtual ObjectWithInitAndDestroyMethods ObjectWithInitAndDestroyMethods() + { + return new ObjectWithInitAndDestroyMethods(); + } + + [Definition(Names = "TheFirstAlias,TheSecondAlias")] + public virtual ObjectWithAnAlias ObjectWithAnAlias() + { + return new ObjectWithAnAlias(); + } + [Definition] [Scope(ObjectScope.Prototype)] public virtual PrototypeChild PrototypeChild() @@ -80,8 +163,43 @@ namespace Spring.Context.Annotation return new SingletonParent(PrototypeChild()); } + [Definition] + [Lazy] + public virtual ImplicitLazyInitObject ImplicitLazyInitObject() + { + return new ImplicitLazyInitObject(); + } + + [Definition] + [Lazy(true)] + public virtual ExplicitLazyInitObject ExplicitLazyInitObject() + { + return new ExplicitLazyInitObject(); + } + + [Definition] + [Lazy(false)] + public virtual ExplicitNonLazyInitObject ExplicitNonLazyInitObject() + { + return new ExplicitNonLazyInitObject(); + } + } + public class TypeRegisteredInXml { } + + public class AnImportedType { } + + public class ImplicitLazyInitObject { } + + public class ExplicitLazyInitObject { } + + public class ExplicitNonLazyInitObject { } + + public class ObjectWithAnAlias { } + + public class SingleNamedObject { } + public class SingletonParent { private PrototypeChild _child; diff --git a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/DefinitionAttributeTests.cs b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/DefinitionAttributeTests.cs new file mode 100644 index 00000000..673a3c85 --- /dev/null +++ b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/DefinitionAttributeTests.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; +using Spring.Context.Attributes; + +namespace Spring.Context.Attributes +{ + [TestFixture] + public class DefinitionAttributeTests + { + [Test] + public void Can_Accept_Single_Name() + { + var def = new DefinitionAttribute(); + + def.Names = "Steve"; + + Assert.That(def.NamesToArray[0], Is.EqualTo("Steve")); + } + + + [Test] + public void Can_Accept_Multiple_Names() + { + var def = new DefinitionAttribute(); + var names = "Name1,Name2,Name3"; + + def.Names = names; + Assert.That(def.NamesToArray[0], Is.EqualTo("Name1")); + Assert.That(def.NamesToArray[1], Is.EqualTo("Name2")); + Assert.That(def.NamesToArray[2], Is.EqualTo("Name3")); + + } + + + } +} diff --git a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ImportResourceAttributeTests.cs b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ImportResourceAttributeTests.cs new file mode 100644 index 00000000..21c83ae1 --- /dev/null +++ b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ImportResourceAttributeTests.cs @@ -0,0 +1,48 @@ +using System; +using System.Collections.Generic; +using System.Text; +using NUnit.Framework; +using Spring.Objects.Factory.Xml; +using Spring.Objects.Factory.Support; + +namespace Spring.Context.Attributes +{ + [TestFixture] + public class ImportResourceAttributeTests + { + [Test] + public void Uses_XmlObjectDefinitionReader_By_Default() + { + var attrib = new ImportResourceAttribute("the resource"); + + Assert.That(attrib.DefinitionReader, Is.EqualTo(typeof(XmlObjectDefinitionReader))); + } + + [Test] + public void Can_Assign_NonDefault_DefinitionReader() + { + var attrib = new ImportResourceAttribute("the resource"); + attrib.DefinitionReader = typeof(AbstractObjectDefinitionReader); + + Assert.That(attrib.DefinitionReader, Is.EqualTo(typeof(AbstractObjectDefinitionReader))); + } + + [Test] + public void DefinitionReader_Can_Prevent_Improper_Types() + { + ImportResourceAttribute attrib = new ImportResourceAttribute("the resource"); + + try + { + attrib.DefinitionReader = typeof(Assert);// <--need to use *anything* ensured *not* to implement IObjectDefinitionReader + Assert.Fail("Expected Exception of type ArgumentException not thrown!"); + } + catch (ArgumentException) + { + //swallow the expected exception + } + + + } + } +} diff --git a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ObjectDefinitions.xml b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ObjectDefinitions.xml new file mode 100644 index 00000000..5c7e700e --- /dev/null +++ b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ObjectDefinitions.xml @@ -0,0 +1,5 @@ + + + + + diff --git a/test/Spring/Spring.Core.Configuration.Tests/Spring.Core.Configuration.Tests.2010.csproj b/test/Spring/Spring.Core.Configuration.Tests/Spring.Core.Configuration.Tests.2010.csproj index f8a5b557..6a7f1d11 100644 --- a/test/Spring/Spring.Core.Configuration.Tests/Spring.Core.Configuration.Tests.2010.csproj +++ b/test/Spring/Spring.Core.Configuration.Tests/Spring.Core.Configuration.Tests.2010.csproj @@ -8,10 +8,11 @@ {4F1A206C-09A8-43FF-B791-FE956E99A120} Library Properties - Spring.Core.Configuration.Tests + Spring Spring.Core.Configuration.Tests - v2.0 + v4.0 512 + true @@ -40,6 +41,9 @@ + + + @@ -55,6 +59,18 @@ {710961A3-0DF4-49E4-A26E-F5B9C044AC84} Spring.Core.2010 + + {44B16BAA-6DF8-447C-9D7F-3AD3D854D904} + Spring.Core.Tests.2010 + + + + + + + + Designer +