diff --git a/src/Spring/Spring.Core.Configuration/Context/Config/AttributeConfigObjectDefinitionParser.cs b/src/Spring/Spring.Core.Configuration/Context/Config/AttributeConfigObjectDefinitionParser.cs
new file mode 100644
index 00000000..9e79a0e5
--- /dev/null
+++ b/src/Spring/Spring.Core.Configuration/Context/Config/AttributeConfigObjectDefinitionParser.cs
@@ -0,0 +1,43 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Spring.Objects.Factory.Xml;
+using Spring.Objects.Factory.Support;
+using Spring.Util;
+using Spring.Context.Attributes;
+using Spring.Objects.Factory.Config;
+
+namespace Spring.Context.Config
+{
+ public class AttributeConfigObjectDefinitionParser : IObjectDefinitionParser
+ {
+ ///
+ /// The object name of the internally managed configuration attribure processor
+ ///
+ public static readonly string CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME = "Spring.Context.Attributes.InternalConfigurationAttributeProcessor";
+
+
+ private static readonly Type ConfigurationClassPostProcessorType = typeof(ConfigurationClassPostProcessor);
+
+ public AttributeConfigObjectDefinitionParser()
+ {
+
+ }
+
+ public Objects.Factory.Config.IObjectDefinition ParseElement(System.Xml.XmlElement element, ParserContext parserContext)
+ {
+ IObjectDefinitionRegistry registry = parserContext.ReaderContext.Registry;
+
+ AssertUtils.ArgumentNotNull(registry, "registry");
+
+ if (!registry.ContainsObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
+ {
+ RootObjectDefinition objectDefinition = new RootObjectDefinition(ConfigurationClassPostProcessorType);
+ objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
+ registry.RegisterObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME, objectDefinition);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/src/Spring/Spring.Core.Configuration/Context/Config/ComponentScanObjectDefinitionParser.cs b/src/Spring/Spring.Core.Configuration/Context/Config/ComponentScanObjectDefinitionParser.cs
new file mode 100644
index 00000000..a39f2956
--- /dev/null
+++ b/src/Spring/Spring.Core.Configuration/Context/Config/ComponentScanObjectDefinitionParser.cs
@@ -0,0 +1,15 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Spring.Objects.Factory.Xml;
+
+namespace Spring.Context.Config
+{
+ public class ComponentScanObjectDefinitionParser
+ {
+ public ComponentScanObjectDefinitionParser()
+ {
+
+ }
+ }
+}
diff --git a/src/Spring/Spring.Core.Configuration/Context/Config/spring-context-1.3.xsd b/src/Spring/Spring.Core.Configuration/Context/Config/spring-context-1.3.xsd
new file mode 100644
index 00000000..7a2ec0eb
--- /dev/null
+++ b/src/Spring/Spring.Core.Configuration/Context/Config/spring-context-1.3.xsd
@@ -0,0 +1,79 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ tag for that purpose.
+ ]]>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Spring/Spring.Core.Configuration/Objects/Factory/Support/AssemblyScanningExtensionMethods.cs b/src/Spring/Spring.Core.Configuration/Objects/Factory/Support/AssemblyScanningExtensionMethods.cs
new file mode 100644
index 00000000..01f4d1b5
--- /dev/null
+++ b/src/Spring/Spring.Core.Configuration/Objects/Factory/Support/AssemblyScanningExtensionMethods.cs
@@ -0,0 +1,150 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Reflection;
+using System.Linq;
+using System.IO;
+using Common.Logging;
+using Spring.Context.Attributes;
+
+namespace Spring.Objects.Factory.Support
+{
+ public static class AssemblyScanningExtensionMethods
+ {
+ private static ILog _logger = LogManager.GetLogger(typeof(AssemblyScanningExtensionMethods));
+
+ ///
+ /// Scans the assemblies for definitions.
+ ///
+ /// The registry.
+ /// The assembly scan path.
+ /// The assembly filename predicate.
+ /// The assembly metadata predicate.
+ ///
+ public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry, string assemblyScanPath, Func assemblyFilenamePredicate, Func assemblyMetadataPredicate)
+ {
+ IEnumerable assemblies = GetAllMatchingAssemblies(assemblyScanPath, assemblyFilenamePredicate);
+
+ assemblies = assemblies.Where(assembly => assemblyMetadataPredicate(assembly));
+
+ IEnumerable configTypes = GetAllConfigurationTypesDefinedIn(assemblies);
+
+ //if we have at least one config class, ensure the post-processor is registered
+ if (configTypes.Count() > 0)
+ {
+ EnsureConfigurationClassPostProcessorIsRegisteredFor(registry);
+ }
+
+ RegisiterDefintionsForConfigTypes(configTypes, registry);
+ }
+
+ ///
+ /// Scans the assemblies for definitions.
+ ///
+ /// The registry.
+ /// The assembly metadata predicate.
+ ///
+ public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry, Func assemblyMetadataPredicate)
+ {
+ ScanAssembliesAndRegisterDefinitions(registry, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fn => true, assemblyMetadataPredicate);
+ }
+
+ ///
+ /// Scans the assemblies for definitions.
+ ///
+ /// The registry.
+ /// The assembly filename predicate.
+ /// The assembly metadata predicate.
+ ///
+ public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry, Func assemblyFilenamePredicate, Func assemblyMetadataPredicate)
+ {
+ ScanAssembliesAndRegisterDefinitions(registry, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), assemblyFilenamePredicate, assemblyMetadataPredicate);
+ }
+
+ public static void ScanAssembliesAndRegisterDefinitions(this IObjectDefinitionRegistry registry)
+ {
+ ScanAssembliesAndRegisterDefinitions(registry, Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fn => true, a => true);
+ }
+
+ ///
+ /// Ensures the configuration class post processor is registered for.
+ ///
+ /// The registry.
+ private static void EnsureConfigurationClassPostProcessorIsRegisteredFor(IObjectDefinitionRegistry registry)
+ {
+ var postProcessorBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
+ if (!registry.ContainsObjectDefinition(postProcessorBuilder.ObjectDefinition.ObjectTypeName))
+ {
+ registry.RegisterObjectDefinition(postProcessorBuilder.ObjectDefinition.ObjectTypeName, postProcessorBuilder.ObjectDefinition);
+ }
+ }
+
+ ///
+ /// Gets all configuration types defined in the assemblies.
+ ///
+ /// The assemblies.
+ ///
+ private static IEnumerable GetAllConfigurationTypesDefinedIn(IEnumerable assemblies)
+ {
+ IList types = new List();
+
+ foreach (Assembly assembly in assemblies)
+ {
+ foreach (Type type in assembly.GetTypes())
+ {
+ if (Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute), true) != null)
+ {
+ types.Add(type);
+ }
+ }
+ }
+
+ return types;
+ }
+
+ ///
+ /// Gets all matching assemblies.
+ ///
+ /// The assembly scan path.
+ /// The assembly filename predicate.
+ ///
+ private static IEnumerable GetAllMatchingAssemblies(string assemblyScanPath, Func assemblyFilenamePredicate)
+ {
+ IList assemblies = new List();
+
+ IEnumerable files = Directory.GetFiles(assemblyScanPath, "*.dll").Where(s => assemblyFilenamePredicate(Path.GetFileName(s)));
+
+ foreach (string file in files)
+ {
+ try
+ {
+ assemblies.Add(Assembly.LoadFrom(file));
+ }
+ catch (Exception ex)
+ {
+ //log and swallow everything that might go wrong here...
+ if (_logger.IsDebugEnabled)
+ _logger.Debug("Failed to load type while scanning Assemblies for Defintions!", ex);
+
+ }
+ }
+
+ return assemblies;
+ }
+
+ ///
+ /// Regisiters the defintions for config types.
+ ///
+ /// The config types.
+ /// The registry.
+ private static void RegisiterDefintionsForConfigTypes(IEnumerable configTypes, IObjectDefinitionRegistry registry)
+ {
+ foreach (Type configType in configTypes)
+ {
+ ObjectDefinitionBuilder definition = ObjectDefinitionBuilder.GenericObjectDefinition(configType);
+ registry.RegisterObjectDefinition(definition.ObjectDefinition.ObjectTypeName, definition.ObjectDefinition);
+ }
+ }
+
+ }
+}
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 422d636c..730a69bc 100644
--- a/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj
+++ b/src/Spring/Spring.Core.Configuration/Spring.Core.Configuration.2010.csproj
@@ -10,8 +10,9 @@
Properties
Spring
Spring.Core.Configuration
- v2.0
+ v3.5
512
+
true
@@ -56,6 +57,7 @@
+
diff --git a/src/Spring/Spring.Core/ContextClassDiagram.cd b/src/Spring/Spring.Core/ContextClassDiagram.cd
new file mode 100644
index 00000000..7a48ca13
--- /dev/null
+++ b/src/Spring/Spring.Core/ContextClassDiagram.cd
@@ -0,0 +1,153 @@
+
+
+
+
+
+ SHQRYAEIiGBAtMBASYTEWAQkWBAiChEMaAACCAFBXMg=
+ Context\Support\AbstractApplicationContext.cs
+
+
+
+
+
+
+ AAQACAAAAABAAACBAAQAAQAAABAAAAAAABAAAAACAEA=
+ Context\Support\AbstractXmlApplicationContext.cs
+
+
+
+
+
+ AAQAAAAAAAAAAAAAAAQAAAAAABAAIAAAAAAAAAAEAAA=
+ Context\Support\GenericApplicationContext.cs
+
+
+
+
+
+ AAAACAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAIAEAAA=
+ Context\Support\XmlApplicationContext.cs
+
+
+
+
+
+ AAEAAAAAAAAAAAAIAAQAAAAAAgAAAAAAAAAAAAAAAAA=
+ Context\Support\StaticApplicationContext.cs
+
+
+
+
+
+ AAAAAAAAAAAAggAAAQAAAAAABAAAAAAAAAAASAAAAAA=
+ Core\IO\ConfigurableResourceLoader.cs
+
+
+
+
+
+
+ AAQAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEA=
+ Context\IConfigurableApplicationContext.cs
+
+
+
+
+
+ AAAAAAAAAAAAEAAAAACAAAQAAAAAAAAAAAAAAAAACAA=
+ Context\IApplicationContext.cs
+
+
+
+
+
+ AAAAAAAAACAAAAAAAAAAQAAAAAAAAAAAIAAAAAAAAAA=
+ Context\ILifecycle.cs
+
+
+
+
+
+ ABAAAAAAAAAAIIAACIAACAAAAAAAAgEMAAAAAAAAAIA=
+ Objects\Factory\IObjectFactory.cs
+
+
+
+
+
+ AAAAAAAAAAAAAACAAAAAAAAIAAQAAAAgEAAAAAAAAAA=
+ Objects\Factory\Config\IAutowireCapableObjectFactory.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAA=
+ Objects\Factory\IHierarchicalObjectFactory.cs
+
+
+
+
+
+ CAAAAAAAAAAAAAAAQABAEAAAAAAAAAAACAAAAAAAAAA=
+ Objects\Factory\IListableObjectFactory.cs
+
+
+
+
+
+ AAAAAAAAAAAAAIAAAIAEAAAgAAAAAAAAAAAACABAAAA=
+ Objects\Factory\Config\IConfigurableListableObjectFactory.cs
+
+
+
+
+
+ AAAAAAAABCAAAAAAAAACAAAAQAAEAAAAAAAAAQAAEAA=
+ Objects\Factory\Config\IConfigurableObjectFactory.cs
+
+
+
+
+
+ AAAAAAAAEAAAABAIAAAAAAAAAAAAAAAAAAAAAgAAAIA=
+ Objects\Factory\Config\ISingletonObjectRegistry.cs
+
+
+
+
+
+ ACAAAAAAAAAAAAAAAAAAAAAACAAAABAAAAAAAAAAAAA=
+ Context\IMessageSource.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA=
+ Context\IApplicationEventPublisher.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAA=
+ Core\IO\IResourceLoader.cs
+
+
+
+
+
+ AAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAQAAAAAAAAIA=
+ Objects\Events\IEventRegistry.cs
+
+
+
+
+
+ CBAAAAAAAAAAAAAAQAAEEAAgABAAAAAAAAAAAAAAEAA=
+ Objects\Factory\Support\IObjectDefinitionRegistry.cs
+
+
+
+
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Spring.Core.2010.csproj b/src/Spring/Spring.Core/Spring.Core.2010.csproj
index 82436338..dd761999 100644
--- a/src/Spring/Spring.Core/Spring.Core.2010.csproj
+++ b/src/Spring/Spring.Core/Spring.Core.2010.csproj
@@ -1218,6 +1218,7 @@
Code
+
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 d1894cf7..5cb6190a 100644
--- a/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs
+++ b/test/Spring/Spring.Core.Configuration.Tests/Context/Attributes/ConfigurationClassPostProcessorTests.cs
@@ -18,11 +18,11 @@ namespace Spring.Context.Attributes
{
_ctx = new GenericApplicationContext();
- var builder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
- _ctx.RegisterObjectDefinition("theConfigClass", builder.ObjectDefinition);
+ var configDefinitionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
+ _ctx.RegisterObjectDefinition(configDefinitionBuilder.ObjectDefinition.ObjectTypeName, configDefinitionBuilder.ObjectDefinition);
- var b2 = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
- _ctx.RegisterObjectDefinition("thePostProcessor", b2.ObjectDefinition);
+ var postProcessorDefintionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
+ _ctx.RegisterObjectDefinition(postProcessorDefintionBuilder.ObjectDefinition.ObjectTypeName, postProcessorDefintionBuilder.ObjectDefinition);
Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(2));
diff --git a/test/Spring/Spring.Core.Configuration.Tests/Objects/Factory/Support/AssemblyScanningExtensionMethodsTests.cs b/test/Spring/Spring.Core.Configuration.Tests/Objects/Factory/Support/AssemblyScanningExtensionMethodsTests.cs
new file mode 100644
index 00000000..89810733
--- /dev/null
+++ b/test/Spring/Spring.Core.Configuration.Tests/Objects/Factory/Support/AssemblyScanningExtensionMethodsTests.cs
@@ -0,0 +1,56 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using NUnit.Framework;
+using System.Reflection;
+using System.Diagnostics;
+using Spring.Context.Config;
+using Spring.Context.Support;
+
+namespace Spring.Objects.Factory.Support
+{
+ [TestFixture]
+ public class AssemblyScanningExtensionMethodsTests
+ {
+ [Test]
+ public void Integration_Scenario_With_Defaults()
+ {
+ GenericApplicationContext context = new GenericApplicationContext();
+ context.ScanAssembliesAndRegisterDefinitions();// (assy => assy.GetTypes().Any(type => type.FullName.Contains("SomeType")));
+ context.Refresh();
+
+ AssertExpectedObjectsAreRegisteredWith(context);
+ }
+
+ [Test]
+ public void Integration_Scenario_With_Filtering_Example()
+ {
+ GenericApplicationContext context = new GenericApplicationContext();
+ context.ScanAssembliesAndRegisterDefinitions(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
+ context.Refresh();
+
+ AssertExpectedObjectsAreRegisteredWith(context);
+ }
+
+ private static void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext context)
+ {
+ Assert.That(context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(13));
+ }
+ [Test]
+ public void Integration_Scenario_With_Complex_Filtering_Example()
+ {
+ GenericApplicationContext context = new GenericApplicationContext();
+ context.ScanAssembliesAndRegisterDefinitions(fn => fn.StartsWith("Spring."), assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
+ context.Refresh();
+
+ AssertExpectedObjectsAreRegisteredWith(context);
+ }
+ }
+
+
+ public class MarkerTypeForScannerToFind
+ {
+
+ }
+}
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 6a7f1d11..5da6ef07 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
@@ -44,6 +44,7 @@
+