removal of Spring.Core.Configuration project and related tests in prep for merge back into trunk

This commit is contained in:
sbohlen
2010-12-02 19:00:02 +00:00
parent d1c29bdcdf
commit 6c7e7777df
32 changed files with 0 additions and 2785 deletions

View File

@@ -74,10 +74,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Web.Mvc.2010", "src\
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Web.Mvc.Tests.2010", "test\Spring\Spring.Web.Mvc.Tests\Spring.Web.Mvc.Tests.2010.csproj", "{D4032434-D9A8-437B-95E8-9D4DE0AD9932}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core.Configuration.2010", "src\Spring\Spring.Core.Configuration\Spring.Core.Configuration.2010.csproj", "{7B65D538-E863-4F57-8DDC-2C38E4150045}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core.Configuration.Tests.2010", "test\Spring\Spring.Core.Configuration.Tests\Spring.Core.Configuration.Tests.2010.csproj", "{4F1A206C-09A8-43FF-B791-FE956E99A120}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|.NET = Debug|.NET
@@ -438,26 +434,6 @@ Global
{D4032434-D9A8-437B-95E8-9D4DE0AD9932}.Release|Any CPU.Build.0 = Release|Any CPU
{D4032434-D9A8-437B-95E8-9D4DE0AD9932}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{D4032434-D9A8-437B-95E8-9D4DE0AD9932}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|.NET.ActiveCfg = Debug|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|.NET.ActiveCfg = Release|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Any CPU.Build.0 = Release|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|.NET.ActiveCfg = Debug|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Any CPU.Build.0 = Debug|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|.NET.ActiveCfg = Release|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Any CPU.ActiveCfg = Release|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Any CPU.Build.0 = Release|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Mixed Platforms.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@@ -1,92 +0,0 @@
#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
}
}

View File

@@ -1,258 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.IO;
using Common.Logging;
using Spring.Util;
namespace Spring.Context.Attributes
{
public interface IAssemblyTypeScanner
{
IAssemblyTypeScanner AssemblyHavingType<T>();
IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate);
IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate);
IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate);
IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource);
IAssemblyTypeScanner IncludeType<T>();
IAssemblyTypeScanner ExcludeType<T>();
IEnumerable<Type> Scan();
}
public abstract class AssemblyTypeScanner : IAssemblyTypeScanner
{
protected readonly List<Predicate<Assembly>> _assemblyPredicates = new List<Predicate<Assembly>>();
protected readonly List<Predicate<Type>> _excludePredicates = new List<Predicate<Type>>();
protected string _folderScanPath;
protected readonly List<Predicate<Type>> _includePredicates = new List<Predicate<Type>>();
protected static ILog _logger = LogManager.GetLogger(typeof(AssemblyTypeScanner));
protected readonly List<IEnumerable<Type>> _typeSources = new List<IEnumerable<Type>>();
/// <summary>
/// Initializes a new instance of the AssemblyTypeScanner class.
/// </summary>
/// <param name="folderScanPath"></param>
public AssemblyTypeScanner(string folderScanPath)
{
if (!string.IsNullOrEmpty(folderScanPath))
{
_folderScanPath = folderScanPath;
}
else
{
_folderScanPath = GetCurrentBinDirectoryPath();
}
}
/// <summary>
/// Initializes a new instance of the AssemblyTypeScanner class.
/// </summary>
public AssemblyTypeScanner()
{
}
public IAssemblyTypeScanner AssemblyHavingType<T>()
{
_typeSources.Add(new AssemblyTypeSource((typeof(T).Assembly)));
return this;
}
public IAssemblyTypeScanner ExcludeType<T>()
{
_excludePredicates.Add(t => t == typeof(T));
return this;
}
public IAssemblyTypeScanner IncludeType<T>()
{
_includePredicates.Add(t => t == typeof(T));
return this;
}
public IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource)
{
AssertUtils.ArgumentNotNull(typeSource, "typeSource");
_typeSources.Add(typeSource);
_includePredicates.Add(t => typeSource.Any(t1 => t1 == t));
return this;
}
public virtual IEnumerable<Type> Scan()
{
SetDefaultFilters();
IList<Type> types = new List<Type>();
foreach (Assembly assembly in GetAllMatchingAssemblies())
{
_typeSources.Add(new AssemblyTypeSource(assembly));
}
foreach (var typeSource in _typeSources)
{
foreach (Type type in typeSource)
{
if (IsIncludedType(type) && !IsExcludedType(type) && FinalVetoConstraintIsSatisfiedBy(type))
{
types.Add(type);
}
}
}
return types;
}
public IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate)
{
_assemblyPredicates.Add(assemblyPredicate);
return this;
}
public IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate)
{
_excludePredicates.Add(predicate);
return this;
}
public IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate)
{
_includePredicates.Add(predicate);
return this;
}
protected virtual bool IsExcludedType(Type type)
{
foreach (var exclude in _excludePredicates)
{
if (exclude(type))
{
return true;
}
}
return false;
}
protected virtual bool IsIncludedAssembly(Assembly assembly)
{
foreach (var include in _assemblyPredicates)
{
if (include(assembly))
{
return true;
}
}
return false;
}
protected virtual bool IsIncludedType(Type type)
{
foreach (var include in _includePredicates)
{
if (include(type))
{
return true;
}
}
return false;
}
protected virtual void SetDefaultFilters()
{
if (_includePredicates.Count == 0)
_includePredicates.Add(t => true);
if (_excludePredicates.Count == 0)
_excludePredicates.Add(t => false);
if (_assemblyPredicates.Count == 0)
_assemblyPredicates.Add(a => true);
}
protected virtual bool FinalVetoConstraintIsSatisfiedBy(Type type)
{
return true;
}
private IEnumerable<Assembly> ApplyAssemblyFiltersTo(IEnumerable<Assembly> assemblyCandidates)
{
IList<Assembly> matchingAssemblies = new List<Assembly>();
foreach (Assembly assemblyCandidate in assemblyCandidates)
if (IsIncludedAssembly(assemblyCandidate))
matchingAssemblies.Add(assemblyCandidate);
return matchingAssemblies;
}
private IEnumerable<Assembly> GetAllAssembliesInPath(string folderPath)
{
IList<Assembly> assemblies = new List<Assembly>();
IEnumerable<string> files = Directory.GetFiles(folderPath, "*.dll");
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;
}
private IEnumerable<Assembly> GetAllMatchingAssemblies()
{
IEnumerable<Assembly> assemblyCandidates = GetAllAssembliesInPath(_folderScanPath);
return ApplyAssemblyFiltersTo(assemblyCandidates);
}
private string GetCurrentBinDirectoryPath()
{
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
}
}
public class AssemblyObjectDefinitionScanner : AssemblyTypeScanner
{
/// <summary>
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
/// </summary>
/// <param name="folderScanPath">The folder scan path.</param>
public AssemblyObjectDefinitionScanner(string folderScanPath)
: base(folderScanPath)
{ }
/// <summary>
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
/// </summary>
public AssemblyObjectDefinitionScanner()
: base(null)
{ }
//protected override bool RequiredConstraintIsSatisfiedBy(Type type)
//{
// return Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute), true) != null;
//}
protected override void SetDefaultFilters()
{
_includePredicates.Add(t => Attribute.GetCustomAttribute(t, typeof(ConfigurationAttribute), true) != null);
base.SetDefaultFilters();
}
}
}

View File

@@ -1,51 +0,0 @@
#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.Collections;
using System.Collections.Generic;
using System.Reflection;
using System.Runtime.InteropServices;
using Spring.Util;
namespace Spring.Context.Attributes
{
public class AssemblyTypeSource : IEnumerable<Type>
{
private readonly _Assembly assembly;
public AssemblyTypeSource(Assembly assembly)
{
AssertUtils.ArgumentNotNull(assembly, "assembly");
this.assembly = assembly;
}
public IEnumerator<Type> GetEnumerator()
{
foreach (var type in assembly.GetTypes())
yield return type;
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
}

View File

@@ -1,74 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Stereotype;
namespace Spring.Context.Attributes
{
/// <summary>
/// Indicates that a class declares one or more <see cref="Definition"/> methods and may be processed
/// by the Spring container to generate object definitions and service requests for those objects
/// at runtime.
///
/// <para>Configuration is meta-annotated as a {@link Component}, therefore Configuration
/// classes are candidates for component-scanning and may also take advantage of
/// <see cref="AutoWired"/> at the field and method but not at the constructor level.
/// </para>
/// <para>May be used in conjunction with the <see cref="Lazy"/> attribute to indicate that all object
/// methods declared within this class are by default lazily initialized.
///</para>
/// <h3>Constraints</h3>
/// <ul>
/// <li>Configuration classes must be non-final</li>
/// <li>Configuration classes must be non-local (may not be declared within a method)</li>
/// <li>Configuration classes must have a default/no-arg constructor and may not use
/// {@link Autowired} constructor parameters</li>
/// </ul>
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class ConfigurationAttribute : ComponentAttribute
{
/// <summary>
/// Initializes a new instance of the ConfigurationAttribute class.
/// </summary>
public ConfigurationAttribute()
{
}
private string _name;
/// <summary>
/// Initializes a new instance of the Configuration class.
/// </summary>
/// <param name="name"></param>
public ConfigurationAttribute(string name)
{
_name = name;
}
/// <summary>
/// Explicitly specify the name of the Spring object definition associated
/// with this Configuration class. If left unspecified (the common case),
/// a object name will be automatically generated.
///
/// <para>The custom name applies only if the Configuration class is picked up via
/// component scanning or supplied directly to a <see cref="AnnotationConfigApplicationContext"/>.
/// If the Configuration class is registered as a traditional XML object definition,
/// the name/id of the object element will take precedence.
/// </para>
/// <see cref="Spring.Objects.Factory.Support.DefaultObjectNameGenerator"/>
/// </summary>
/// <value>The name.</value>
public string Name
{
get { return _name; }
set
{
_name = value;
}
}
}
}

View File

@@ -1,163 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Core.IO;
using Spring.Collections.Generic;
using Spring.Objects.Factory.Parsing;
namespace Spring.Context.Attributes
{
public class ConfigurationClass
{
private Type _configurationClassType;
private IDictionary<string, Type> _importedResources = new Dictionary<string, Type>();
private ISet<ConfigurationClassMethod> _methods = new HashedSet<ConfigurationClassMethod>();
private string _objectName;
private IResource _resource;
/// <summary>
/// Initializes a new instance of the ConfigurationClass class.
/// </summary>
/// <param name="objectName"></param>
/// <param name="type"></param>
public ConfigurationClass(string objectName, Type type)
{
this._objectName = objectName;
this._configurationClassType = type;
}
public Type ConfigurationClassType
{
get
{
return _configurationClassType;
}
}
public IDictionary<string, Type> ImportedResources
{
get
{
return _importedResources;
}
}
public ISet<ConfigurationClassMethod> Methods
{
get
{
return _methods;
}
}
public string ObjectName
{
get
{
return _objectName;
}
set
{
_objectName = value;
}
}
public IResource Resource
{
get
{
return _resource;
}
}
public string SimpleName
{
get { return ConfigurationClassType.Name; }
}
public void AddImportedResource(string importedResource, Type readerClass)
{
_importedResources.Add(importedResource, readerClass);
}
public override bool Equals(object other)
{
return this == other || (other is ConfigurationClass && ConfigurationClassType.Name.Equals(((ConfigurationClass)other).ConfigurationClassType.Name));
}
public override int GetHashCode()
{
return ConfigurationClassType.Name.GetHashCode() * 14;
}
public void Validate(IProblemReporter problemReporter)
{
// 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<String, int> methodNameCounts = new Dictionary<String, int>();
foreach (ConfigurationClassMethod method in _methods)
{
String dClassName = method.MethodMetadata.DeclaringType.FullName;
String methodName = method.MethodMetadata.Name;
String fqMethodName = dClassName + hashDelim + methodName;
if (!methodNameCounts.ContainsKey(fqMethodName))
{
methodNameCounts.Add(fqMethodName, 1);
}
else
{
int currentCount = methodNameCounts[fqMethodName];
methodNameCounts.Add(fqMethodName, currentCount++);
}
}
foreach (String methodName in methodNameCounts.Keys)
{
int count = methodNameCounts[methodName];
if (count > 1)
{
String shortMethodName = methodName.Substring(methodName.IndexOf(hashDelim) + 1);
problemReporter.Error(new ObjectMethodOverloadingProblem(shortMethodName, count, Resource, ConfigurationClassType));
}
}
if (Attribute.GetCustomAttribute(_configurationClassType, typeof(ConfigurationAttribute)) != null)
{
if (ConfigurationClassType.IsSealed)
{
problemReporter.Error(new SealedConfigurationProblem(SimpleName, Resource, ConfigurationClassType));
}
foreach (ConfigurationClassMethod method in _methods)
{
method.Validate(problemReporter);
}
}
}
private class SealedConfigurationProblem : Problem
{
public SealedConfigurationProblem(string name, IResource resource, Type configurationClassType)
: base(String.Format("[Configuration] class '{0}' may not be sealed. Remove the sealed modifier to continue.", name), new Location(resource, configurationClassType))
{ }
}
private class ObjectMethodOverloadingProblem : Problem
{
public ObjectMethodOverloadingProblem(string methodName, int count, IResource resource, Type configurationClassType)
: base(String.Format("[Configuration] class '{0}' has {1} overloaded [Definiton] methods named '{2}'. " +
"Only one [Definition] method of a given name is allowed within each [Configuration] class.", configurationClassType.Name, count, methodName), new Location(resource, configurationClassType))
{ }
}
}
}

View File

@@ -1,123 +0,0 @@
#region License
/*
* Copyright © 2002-2010 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.Collections.Generic;
using System;
using System.Text;
using Spring.Core.IO;
using System.Reflection;
using Spring.Objects.Factory.Parsing;
namespace Spring.Context.Attributes
{
/**
* 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 ConfigurationClassObjectDefinitionReader
*/
public class ConfigurationClassMethod
{
private ConfigurationClass _configurationClass;
private MethodInfo _methodInfo;
/// <summary>
/// Initializes a new instance of the ConfigurationClassMethod class.
/// </summary>
/// <param name="methodInfo"></param>
/// <param name="configurationClass"></param>
public ConfigurationClassMethod(MethodInfo methodInfo, ConfigurationClass configurationClass)
{
_methodInfo = methodInfo;
_configurationClass = configurationClass;
}
public ConfigurationClass ConfigurationClass
{
get
{
return _configurationClass;
}
}
public MethodInfo MethodMetadata
{
get
{
return _methodInfo;
}
}
public Location ResourceLocation
{
get { return new Location(_configurationClass.Resource, _methodInfo); }
}
public override string ToString()
{
return string.Format("{0}:name={1},declaringClass={2}", this.GetType().Name, _methodInfo.Name, _methodInfo.DeclaringType.FullName);
}
public void Validate(IProblemReporter problemReporter)
{
//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)
{
problemReporter.Error(new NonVirtualMethodError(MethodMetadata.Name, ResourceLocation));
}
}
else
{
if (MethodMetadata.IsStatic)
{
problemReporter.Error(new StaticMethodError(MethodMetadata.Name, ResourceLocation));
}
}
}
private class StaticMethodError : Problem
{
public StaticMethodError(string methodName, Location location)
: base(String.Format("Method '{0}' must not be static; remove the method's static modifier to continue",
methodName), location)
{ }
}
private class NonVirtualMethodError : Problem
{
public NonVirtualMethodError(string methodName, Location location)
: base(String.Format("Method '{0}' must be public virtual; change the method's modifiers to continue",
methodName), location)
{ }
}
}
}

View File

@@ -1,229 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Parsing;
using Spring.Collections.Generic;
using System.Reflection;
using Spring.Objects.Factory.Config;
using Common.Logging;
using Spring.Objects;
using Spring.Util;
namespace Spring.Context.Attributes
{
public class ConfigurationClassObjectDefinitionReader
{
private readonly ILog _logger = LogManager.GetLogger(typeof(ConfigurationClassObjectDefinitionReader));
private IProblemReporter _problemReporter;
private IObjectDefinitionRegistry _registry;
/// <summary>
/// Initializes a new instance of the ConfigurationClassObjectDefinitionReader class.
/// </summary>
/// <param name="registry"></param>
/// <param name="problemReporter"></param>
public ConfigurationClassObjectDefinitionReader(IObjectDefinitionRegistry registry, IProblemReporter problemReporter)
{
_registry = registry;
_problemReporter = problemReporter;
}
public static bool CheckConfigurationClassCandidate(Type type)
{
if (type != null)
{
return (Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute)) != null);
}
return false;
}
public void LoadObjectDefinitions(ISet<ConfigurationClass> configurationModel)
{
foreach (ConfigurationClass configClass in configurationModel)
{
LoadObjectDefinitionsForConfigurationClass(configClass);
}
}
private void LoadObjectDefinitionForConfigurationClassIfNecessary(ConfigurationClass configClass)
{
if (configClass.ObjectName != null)
{
// a Object definition already exists for this configuration class -> nothing to do
return;
}
// no Object definition exists yet -> this must be an imported configuration class (@Import).
GenericObjectDefinition configObjectDef = new GenericObjectDefinition();
String className = configClass.ConfigurationClassType.Name;
configObjectDef.ObjectType = configClass.ConfigurationClassType;
if (CheckConfigurationClassCandidate(configClass.ConfigurationClassType))
{
String configObjectName = ObjectDefinitionReaderUtils.RegisterWithGeneratedName(configObjectDef, _registry);
configClass.ObjectName = configObjectName;
if (_logger.IsDebugEnabled)
{
_logger.Debug(String.Format("Registered object definition for imported [Configuration] class {0}", configObjectName));
}
}
}
private void LoadObjectDefinitionsForConfigurationClass(ConfigurationClass configClass)
{
LoadObjectDefinitionForConfigurationClassIfNecessary(configClass);
foreach (ConfigurationClassMethod method in configClass.Methods)
{
LoadObjectDefinitionsForModelMethod(method);
}
LoadObjectDefinitionsFromImportedResources(configClass.ImportedResources);
}
private void LoadObjectDefinitionsForModelMethod(ConfigurationClassMethod method)
{
ConfigurationClass configClass = method.ConfigurationClass;
MethodInfo metadata = method.MethodMetadata;
RootObjectDefinition objDef = new ConfigurationClassObjectDefinition();
//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;
//ObjectDef.setAttribute(RequiredAnnotationObjectPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
// consider name and any aliases
//Dictionary<String, Object> ObjectAttributes = metadata.getAnnotationAttributes(Object.class.getName());
object[] objectAttributes = metadata.GetCustomAttributes(typeof(DefinitionAttribute), true);
List<string> names = new List<string>();
for (int i = 0; i < objectAttributes.Length; i++)
{
string[] namesAndAliases = ((DefinitionAttribute)objectAttributes[i]).NamesToArray;
if (namesAndAliases != null)
{
names.Add(metadata.Name);
}
else
{
namesAndAliases = new[] { metadata.Name };
}
for (int j = 0; j < namesAndAliases.Length; j++)
{
names.Add(namesAndAliases[j]);
}
}
string objectName = (names.Count > 0 ? names[0] : method.MethodMetadata.Name);
for (int i = 1; i < names.Count; i++)
{
_registry.RegisterAlias(objectName, names[i]);
}
// has this already been overridden (e.g. via XML)?
if (_registry.ContainsObjectDefinition(objectName))
{
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 Object definition for {0}: a definition for object " +
"'{1}' already exists. This is likely due to an override in XML.", method, objectName));
}
return;
}
}
if (Attribute.GetCustomAttribute(metadata, typeof(PrimaryAttribute)) != null)
{
//TODO: determine how to respond to this attribute's presence
//ObjectDef.isPrimary = true;
}
// is this Object to be instantiated lazily?
if (Attribute.GetCustomAttribute(metadata, typeof(LazyAttribute)) != null)
{
objDef.IsLazyInit = (Attribute.GetCustomAttribute(metadata, typeof(LazyAttribute)) as LazyAttribute).LazyInitialize;
}
if (Attribute.GetCustomAttribute(metadata, typeof(DependsOnAttribute)) != null)
{
objDef.DependsOn = (Attribute.GetCustomAttribute(metadata, typeof(DependsOnAttribute)) as DependsOnAttribute).Name;
}
//Autowire autowire = (Autowire) ObjectAttributes.get("autowire");
//if (autowire.isAutowire()) {
// ObjectDef.setAutowireMode(autowire.value());
//}
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)
{
objDef.Scope = (Attribute.GetCustomAttribute(metadata, typeof(ScopeAttribute)) as ScopeAttribute).ObjectScope.ToString();
}
if (_logger.IsDebugEnabled)
{
_logger.Debug(String.Format("Registering Object definition for [Definition] method {0}.{1}()", configClass.ConfigurationClassType.Name, objectName));
}
_registry.RegisterObjectDefinition(objectName, objDef);
}
private void LoadObjectDefinitionsFromImportedResources(IDictionary<string, Type> importedResources)
{
IDictionary<Type, IObjectDefinitionReader> readerInstanceCache = new Dictionary<Type, IObjectDefinitionReader>();
foreach (KeyValuePair<string, Type> entry in importedResources)
{
String resource = entry.Key;
Type readerClass = entry.Value;
if (!readerInstanceCache.ContainsKey(readerClass))
{
try
{
IObjectDefinitionReader readerInstance =
(IObjectDefinitionReader)Activator.CreateInstance(readerClass, _registry);
readerInstanceCache.Add(readerClass, readerInstance);
}
catch (Exception)
{
throw new InvalidOperationException(String.Format("Could not instantiate IObjectDefinitionReader class {0}", readerClass.FullName));
}
}
IObjectDefinitionReader reader = readerInstanceCache[readerClass];
reader.LoadObjectDefinitions(resource);
}
}
private class ConfigurationClassObjectDefinition : RootObjectDefinition
{
}
}
}

View File

@@ -1,138 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Parsing;
using Spring.Collections.Generic;
using Spring.Util;
using System.Reflection;
namespace Spring.Context.Attributes
{
public class ConfigurationClassParser
{
private ISet<ConfigurationClass> _configurationClasses = new HashedSet<ConfigurationClass>();
private Stack<ConfigurationClass> _importStack = new Stack<ConfigurationClass>();
private IProblemReporter _problemReporter;
/// <summary>
/// Initializes a new instance of the ConfigurationClassParser class.
/// </summary>
/// <param name="problemReporter"></param>
public ConfigurationClassParser(IProblemReporter problemReporter)
{
_problemReporter = problemReporter;
}
public ISet<ConfigurationClass> ConfigurationClasses
{
get { return _configurationClasses; }
}
//public void Parse(String className, String ObjectName)
//{
// ProcessConfigurationClass(new ConfigurationClass(className, ObjectName));
//}
public void Parse(Type type, string objectName)
{
ProcessConfigurationClass(new ConfigurationClass(objectName, type));
}
public void Validate()
{
foreach (ConfigurationClass configClass in ConfigurationClasses)
{
configClass.Validate(_problemReporter);
}
}
protected void ProcessConfigurationClass(ConfigurationClass configurationClass)
{
DoProcessConfigurationClass(configurationClass);
if (ConfigurationClasses.Contains(configurationClass) && configurationClass.ObjectName != null)
{
// Explicit object definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
ConfigurationClasses.Remove(configurationClass);
}
ConfigurationClasses.Add(configurationClass);
}
private void DoProcessConfigurationClass(ConfigurationClass configurationClass)
{
if (Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportAttribute)) != null)
{
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, typeof(ImportResourceAttribute)) as ImportResourceAttribute;
foreach (string resource in attrib.Resources)
{
configurationClass.AddImportedResource(resource, attrib.DefinitionReader);
}
}
ISet<MethodInfo> definitionMethods = GetAllMethodsWithCustomAttributeForClass(configurationClass.ConfigurationClassType, typeof(DefinitionAttribute));
foreach (MethodInfo definitionMethod in definitionMethods)
{
configurationClass.Methods.Add(new ConfigurationClassMethod(definitionMethod, configurationClass));
}
}
private ISet<MethodInfo> GetAllMethodsWithCustomAttributeForClass(Type theClass, Type customAttribute)
{
ISet<MethodInfo> methods = new HashedSet<MethodInfo>();
foreach (MethodInfo method in theClass.GetMethods())
{
if (Attribute.GetCustomAttribute(method, customAttribute) != null)
{
methods.Add(method);
}
}
return methods;
}
private void ProcessImport(ConfigurationClass configClass, Type[] classesToImport)
{
if (_importStack.Contains(configClass))
{
_problemReporter.Error(new CircularImportProblem(configClass, _importStack, configClass.ConfigurationClassType));
}
else
{
_importStack.Push(configClass);
foreach (Type classToImport in classesToImport)
{
ProcessConfigurationClass(new ConfigurationClass(null, classToImport));
}
_importStack.Pop();
}
}
private class CircularImportProblem : Problem
{
public CircularImportProblem(ConfigurationClass configClass, Stack<ConfigurationClass> importStack, Type configurationClassType)
: base(String.Format("A circular @Import has been detected: " +
"Illegal attempt by [Configuration] class '{0}' to import class '{1}' as '{2}' is " +
"already present in the current import stack [{3}]",
importStack.Peek().SimpleName, configClass.SimpleName,
configClass.SimpleName, importStack),
new Location(importStack.Peek().Resource, configurationClassType)
)
{ }
}
}
}

View File

@@ -1,198 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Common.Logging;
using Spring.Objects.Factory.Parsing;
using Spring.Objects.Factory.Support;
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
{
public class ConfigurationClassPostProcessor : IObjectDefinitionRegistryPostProcessor, IOrdered
{
private ILog _logger = LogManager.GetLogger(typeof(ConfigurationClassPostProcessor));
private bool _postProcessObjectDefinitionRegistryCalled = false;
private bool _postProcessObjectFactoryCalled = false;
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)
{
throw new InvalidOperationException("PostProcessObjectDefinitionRegistry already called for this post-processor");
}
if (_postProcessObjectFactoryCalled)
{
throw new InvalidOperationException("PostProcessObjectFactory already called for this post-processor");
}
_postProcessObjectDefinitionRegistryCalled = true;
ProcessConfigObjectDefinitions(registry);
}
public void PostProcessObjectFactory(IConfigurableListableObjectFactory objectFactory)
{
if (_postProcessObjectFactoryCalled)
{
throw new InvalidOperationException(
"PostProcessObjectFactory already called for this post-processor");
}
_postProcessObjectFactoryCalled = true;
if (!_postProcessObjectDefinitionRegistryCalled)
{
// ObjectDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigObjectDefinitions 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)
{
ISet<ObjectDefinitionHolder> configCandidates = new HashedSet<ObjectDefinitionHolder>();
foreach (string objectName in registry.GetObjectDefinitionNames())
{
IObjectDefinition objectDef = registry.GetObjectDefinition(objectName);
if (ConfigurationClassObjectDefinitionReader.CheckConfigurationClassCandidate(objectDef.ObjectType))
{
configCandidates.Add(new ObjectDefinitionHolder(objectDef, objectName));
}
}
//if nothing to process, bail out
if (configCandidates.Count == 0) { return; }
ConfigurationClassParser parser = new ConfigurationClassParser(_problemReporter);
foreach (ObjectDefinitionHolder holder in configCandidates)
{
IObjectDefinition bd = holder.ObjectDefinition;
try
{
if (bd is AbstractObjectDefinition && ((AbstractObjectDefinition)bd).HasObjectType)
{
parser.Parse(((AbstractObjectDefinition)bd).ObjectType, holder.ObjectName);
}
else
{
//parser.Parse(bd.ObjectTypeName, holder.ObjectName);
}
}
catch (ObjectDefinitionParsingException ex)
{
throw new ObjectDefinitionStoreException("Failed to load object class: " + bd.ObjectTypeName, ex);
}
}
parser.Validate();
// Read the model and create Object definitions based on its content
ConfigurationClassObjectDefinitionReader reader = new ConfigurationClassObjectDefinitionReader(registry, _problemReporter);
reader.LoadObjectDefinitions(parser.ConfigurationClasses);
}
public class ObjectFactoryTargetSource : ITargetSource
{
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
}
}
}

View File

@@ -1,96 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Config;
using Spring.Util;
namespace Spring.Context.Attributes
{
[AttributeUsage(AttributeTargets.Method)]
public class DefinitionAttribute : Attribute
{
private AutoWiringMode _autoWire = AutoWiringMode.No;
private string _destroyMethod;
private string _initMethod;
private string _names;
/// <summary>
/// Are dependencies to be injected via autowiring?
/// </summary>
/// <value>The auto wire.</value>
public AutoWiringMode AutoWire
{
get { return _autoWire; }
set
{
_autoWire = value;
}
}
/// <summary>
/// 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.
/// <para>
/// Note: Only invoked on objects whose lifecycle is under the full control of the
/// factory, which is always the case for singletons but not guaranteed
/// for any other scope.
/// </para>
/// <see cref="Spring.Context.IConfigurableApplicationContext"/>
/// </summary>
/// <value>The destroy method.</value>
public string DestroyMethod
{
get { return _destroyMethod; }
set
{
_destroyMethod = value;
}
}
/// <summary>
/// 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 Object-annotated method.
/// </summary>
/// <value>The init method.</value>
public string InitMethod
{
get { return _initMethod; }
set
{
_initMethod = value;
}
}
/// <summary>
/// The name of this object, or if plural, aliases for this object. If left unspecified
/// the name of the object is the name of the attributed method. If specified, the method
/// name is ignored.
/// </summary>
/// <value>The name.</value>
public string Names
{
get
{
return _names;
}
set
{
_names = value;
}
}
public string[] NamesToArray
{
get
{
return StringUtils.DelimitedListToStringArray(_names, ",");
}
}
}
}

View File

@@ -1,45 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Spring.Context.Attributes
{
/// <summary>
/// objects on which the current object depends. Any objects specified are guaranteed to be
/// created by the container before this object. Used infrequently in cases where a object
/// does not explicitly depend on another through properties or constructor arguments,
/// but rather depends on the side effects of another object's initialization.
/// <para>Note: This attribute will not be inherited by child object definitions,
/// hence it needs to be specified per concrete object definition.
/// </para>
/// <para>Using <see cref="DependsOn"/> at the class level has no effect unless component-scanning
/// is being used. If a <see cref="DependsOn"/>-attributed class is declared via XML,
/// <see cref="DependsOn"/> attribute metadata is ignored, and
/// &lt;object depends-on="..."/&gt; is respected instead.
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class DependsOnAttribute : Attribute
{
private string[] _name;
/// <summary>
/// Initializes a new instance of the DependsOn class.
/// </summary>
/// <param name="name"></param>
public DependsOnAttribute(string[] name)
{
_name = name;
}
public string[] Name
{
get { return _name; }
set
{
_name = value;
}
}
}
}

View File

@@ -1,53 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Spring.Context.Attributes
{
/// <summary>
/// Indicates one or more <see cref="Configuration"/> classes to import.
///
/// <para>Provides functionality equivalent to the :lt;import/&gt; element in Spring XML.
/// Only supported for actual <see cref="Configuration"/>-attributed classes.
/// </para>
///
/// <para><see cref="Definition"/> definitions declared in imported <see cref="Configuration"/> classes
/// should be accessed by using <see cref="AutoWired"/> injection. Either the object
/// itself can be autowired, or the configuration class instance declaring the object can be
/// autowired. The latter approach allows for explicit, IDE-friendly navigation between
/// <see cref="Configuration"/> class methods.
/// </para>
///
/// <para>If XML or other non-<see cref="Configuration"/> object definition resources need to be
/// imported, use <see cref="ImportResource"/>
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class ImportAttribute : Attribute
{
private Type[] _types;
/// <summary>
/// Initializes a new instance of the Import class.
/// </summary>
/// <param name="types"></param>
public ImportAttribute(Type[] types)
{
_types = types;
}
/// <summary>
/// The <see cref="Configuration"/> class or classes to import.
/// </summary>
/// <value>The type.</value>
public Type[] Types
{
get { return _types; }
set
{
_types = value;
}
}
}
}

View File

@@ -1,80 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Xml;
using Spring.Util;
namespace Spring.Context.Attributes
{
/// <summary>
///
/// </summary>
[AttributeUsage(AttributeTargets.Class)]
public class ImportResourceAttribute : Attribute
{
private Type _objectDefinitionReader = typeof(XmlObjectDefinitionReader);
private string[] _resources;
/// <summary>
/// Initializes a new instance of the ImportResourceAttribute class.
/// </summary>
/// <param name="resources"></param>
public ImportResourceAttribute(string[] resources)
{
if (resources ==null || resources.Length ==0)
throw new ArgumentException("resources cannot be null or empty!");
_resources = resources;
}
/// <summary>
/// Initializes a new instance of the ImportResourceAttribute class.
/// </summary>
/// <param name="resource"></param>
public ImportResourceAttribute(string resource)
{
if (StringUtils.IsNullOrEmpty(resource))
throw new ArgumentException("resource cannot be null or empty!");
_resources = new[] { resource };
}
/// <summary>
/// <see cref="IObjectDefinitionReader"/> implementation to use when processing resources specified
/// by the <see cref="Resources"/> attribute.
/// </summary>
/// <value>The <see cref="IObjectDefinitionReader"/>.</value>
public Type DefinitionReader
{
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;
}
}
/// <summary>
/// Resource paths to import. Resource-loading prefixes such as <code>assembly://</code> and
/// <code>file://</code>, etc may be used.
/// </summary>
/// <value>The resources.</value>
public string[] Resources
{
get { return _resources; }
set
{
_resources = value;
}
}
}
}

View File

@@ -1,61 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Spring.Context.Attributes
{
/// <summary>
/// Indicates whether a object is to be lazily initialized.
///
/// <para>If this annotation is not present on a Component or object definition, eager
/// initialization will occur. If present and set to true, the
/// object/Component will not be initialized until referenced by another object or
/// explicitly retrieved from the enclosing <see cref="Spring.Objects.Factory.IObjectFactory"/>.
/// If present and set to false, the object will be instantiated on startup by object factories
/// that perform eager initialization of singletons.
/// </para>
/// <para>
/// If Lazy is present on a <see cref="Configuration"/> class, this indicates that all
/// <see cref="Definition"/> methods within that <see cref="Configuration"/> should be lazily
/// initialized. If Lazy is present and false on a object method within a
/// Lazy-annotated Configuration class, this indicates overriding the 'default
/// lazy' behavior and that the object should be eagerly initialized.
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
public class LazyAttribute : Attribute
{
private bool _lazyInitialize = true;
/// <summary>
/// Initializes a new instance of the LazyAttribute class.
/// </summary>
/// <param name="lazyInitialize"></param>
public LazyAttribute(bool lazyInitialize)
{
_lazyInitialize = lazyInitialize;
}
/// <summary>
/// Initializes a new instance of the LazyAttribute class.
/// </summary>
public LazyAttribute()
{
}
/// <summary>
/// Whether lazy initialization should occur.
/// </summary>
/// <value><c>true</c> if [lazy initialize]; otherwise, <c>false</c>.</value>
public bool LazyInitialize
{
get { return _lazyInitialize; }
set
{
_lazyInitialize = value;
}
}
}
}

View File

@@ -1,23 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
namespace Spring.Context.Attributes
{
/// <summary>
/// Indicates that an object should be given preference when multiple candidates
/// are qualified to autowire a single-valued dependency. If exactly one 'primary'
/// object exists among the candidates, it will be the autowired value.
///
/// <para>Using <see cref="Primary"/> at the class level has no effect unless component-scanning
/// is being used. If a <see cref="Primary"/>-attributed class is declared via XML,
/// <see cref="Primary"/> attribute metadata is ignored, and
/// <code>&lt;object primary="true|false"/&gt;></code> is respected instead.
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class PrimaryAttribute : Attribute
{
}
}

View File

@@ -1,48 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Support;
namespace Spring.Context.Attributes
{
/// <summary>
/// When used as a type-level attribute, indicates the name of a scope to use
/// for instances of the attributed type.
///
/// <para>When used as a method-level attribute in conjunction with the
/// <see cref="Definition"/> attribute, indicates the name of a scope to use for
/// the instance returned from the method.
/// </para>
/// <para>In this context, scope means the lifecycle of an instance, such as
/// <code>singleton</code>, <code>prototype</code>, and so forth.
/// </para>
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class ScopeAttribute : Attribute
{
private ObjectScope _scope = ObjectScope.Singleton;
/// <summary>
/// Initializes a new instance of the Scope class.
/// </summary>
/// <param name="scope"></param>
public ScopeAttribute(ObjectScope scope)
{
_scope = scope;
}
/// <summary>
/// Specifies the scope to use for the annotated object.
/// </summary>
/// <value>The scope.</value>
public ObjectScope ObjectScope
{
get { return _scope; }
set
{
_scope = value;
}
}
}
}

View File

@@ -1,43 +0,0 @@
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
{
/// <summary>
/// The object name of the internally managed configuration attribure processor
/// </summary>
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;
}
}
}

View File

@@ -1,15 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Xml;
namespace Spring.Context.Config
{
public class ComponentScanObjectDefinitionParser
{
public ComponentScanObjectDefinitionParser()
{
}
}
}

View File

@@ -1,41 +0,0 @@
using System;
using System.Collections.Generic;
using System.Text;
using Spring.Objects.Factory.Xml;
namespace Spring.Context.Config
{
/// <summary>
/// <code>NamespaceParser</code> 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
/// <code>&lt;tx:advice&gt;</code> elements, the other uses attributes
/// in combination with the <code>&lt;tx:annotation-driven&gt;</code> element.
/// Both approached are detailed in the Spring reference manual.
/// </summary>
[
NamespaceParser(
Namespace = "http://www.springframework.net/context",
SchemaLocationAssemblyHint = typeof(ContextNamespaceParser),
SchemaLocation = "/Spring.Context.Config/spring-context-1.3.xsd"
)
]
public class ContextNamespaceParser : NamespaceParserSupport
{
/// <summary>
/// Register the <see cref="IObjectDefinitionParser"/> for the '<code>advice</code>' and
/// '<code>attribute-driven'</code> tags.
/// </summary>
public override void Init()
{
RegisterObjectDefinitionParser("attribute-config", new AttributeConfigObjectDefinitionParser());
//RegisterObjectDefinitionParser("component-scan", new ComponentScanObjectDefinitionParser());
}
}
}

View File

@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<xsd:schema xmlns="http://www.springframework.net/context"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:objects="http://www.springframework.net"
xmlns:tool="http://www.springframework.net/tool"
targetNamespace="http://www.springframework.net/context"
elementFormDefault="qualified"
attributeFormDefault="unqualified">
<xsd:import namespace="http://www.springframework.net"/>
<xsd:import namespace="http://www.springframework.net/tool"/>
<xsd:annotation>
<xsd:documentation><![CDATA[
Defines the configuration elements for the Spring Framework's application
context support. Effects the activation of various configuration styles
for the containing Spring ApplicationContext.
]]></xsd:documentation>
</xsd:annotation>
<xsd:element name="attribute-config">
<xsd:annotation>
<xsd:documentation><![CDATA[
Activates various annotations to be detected in bean classes: Spring's @Required and
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
choose to activate the individual BeanPostProcessors for those annotations.
Note: This tag does not activate processing of Spring's @Transactional or EJB3's
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
tag for that purpose.
]]></xsd:documentation>
</xsd:annotation>
</xsd:element>
<xsd:element name="component-scan">
<xsd:annotation>
<xsd:documentation><![CDATA[
Scans the classpath for annotated components that will be auto-registered as
Spring beans. By default, the Spring-provided @Component, @Repository,
@Service, and @Controller stereotypes will be detected.
Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
annotations in the component classes, which is usually desired for autodetected components
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
this default behavior, for example in order to use custom BeanPostProcessor definitions
for handling those annotations.
Note: You may use placeholders in package paths, but only resolved against system
properties (analogous to resource paths). A component scan results in new bean definition
being registered; Spring's PropertyPlaceholderConfigurer will apply to those bean
definitions just like to regular bean definitions, but it won't apply to the component
scan settings themselves.
]]></xsd:documentation>
</xsd:annotation>
<xsd:complexType>
<xsd:attribute name="attribute-config" type="xsd:boolean"
default="true">
<xsd:annotation>
<xsd:documentation><![CDATA[
Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
<xsd:attribute name="name-generator" type="xsd:string">
<xsd:annotation>
<xsd:documentation><![CDATA[
The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
]]></xsd:documentation>
</xsd:annotation>
</xsd:attribute>
</xsd:complexType>
</xsd:element>
</xsd:schema>

View File

@@ -1,87 +0,0 @@
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
{
public static void Scan(this IObjectDefinitionRegistry registry, IAssemblyTypeScanner scanner)
{
IEnumerable<Type> configTypes = scanner.Scan();
//if we have at least one config class, ensure the post-processor is registered
if (configTypes.Count() > 0)
{
EnsureConfigurationClassPostProcessorIsRegisteredFor(registry);
}
RegisiterDefintionsForTypes(configTypes, registry);
}
public static void Scan(this IObjectDefinitionRegistry registry)
{
Scan(registry, new AssemblyObjectDefinitionScanner());
}
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Type> typePredicate)
{
Scan(registry, null, ta => true, typePredicate);
}
public static void Scan(this IObjectDefinitionRegistry registry, string assemblyScanPath, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
{
//create a scanner instance using the scan path
IAssemblyTypeScanner scanner = new AssemblyObjectDefinitionScanner(assemblyScanPath);
//configure the scanner per the provided constraints
scanner.WithAssemblyFilter(assemblyPredicate).WithIncludeFilter(typePredicate);
//pass the scanner to primary Scan method to actually do the work
Scan(registry, scanner);
}
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
{
Scan(registry, null, assemblyPredicate, typePredicate);
}
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate)
{
Scan(registry, null, assemblyPredicate, t => true);
}
/// <summary>
/// Ensures the configuration class post processor is registered for.
/// </summary>
/// <param name="registry">The registry.</param>
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);
}
}
/// <summary>
/// Regisiters the defintions for types.
/// </summary>
/// <param name="typesToRegister">The types to register.</param>
/// <param name="registry">The registry.</param>
private static void RegisiterDefintionsForTypes(IEnumerable<Type> typesToRegister, IObjectDefinitionRegistry registry)
{
foreach (Type type in typesToRegister)
{
ObjectDefinitionBuilder definition = ObjectDefinitionBuilder.GenericObjectDefinition(type);
registry.RegisterObjectDefinition(definition.ObjectDefinition.ObjectTypeName, definition.ObjectDefinition);
}
}
}
}

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Spring.Core.Configuration")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Spring.Core.Configuration")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("aa7c95ac-e82f-4c33-a857-76b179c34166")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,88 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{7B65D538-E863-4F57-8DDC-2C38E4150045}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Spring</RootNamespace>
<AssemblyName>Spring.Core.Configuration</AssemblyName>
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Common.Logging">
<HintPath>..\..\..\lib\Net\2.0\Common.Logging.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Context\Advice\SpringObjectMethodInterceptor.cs" />
<Compile Include="Context\Attributes\AssemblyObjectDefinitionScanner.cs" />
<Compile Include="Context\Attributes\AssemblyTypeSource.cs" />
<Compile Include="Context\Attributes\ConfigurationAttribute.cs" />
<Compile Include="Context\Attributes\ConfigurationClass.cs" />
<Compile Include="Context\Attributes\ConfigurationClassMethod.cs" />
<Compile Include="Context\Attributes\ConfigurationClassObjectDefinitionReader.cs" />
<Compile Include="Context\Attributes\ConfigurationClassParser.cs" />
<Compile Include="Context\Attributes\ConfigurationClassPostProcessor.cs" />
<Compile Include="Context\Attributes\DefinitionAttribute.cs" />
<Compile Include="Context\Attributes\DependsOnAttribute.cs" />
<Compile Include="Context\Attributes\ImportAttribute.cs" />
<Compile Include="Context\Attributes\ImportResourceAttribute.cs" />
<Compile Include="Context\Attributes\LazyAttribute.cs" />
<Compile Include="Context\Attributes\PrimaryAttribute.cs" />
<Compile Include="Context\Attributes\ScopeAttribute.cs" />
<Compile Include="Context\Config\AttributeConfigObjectDefinitionParser.cs" />
<Compile Include="Context\Config\ComponentScanObjectDefinitionParser.cs" />
<Compile Include="Context\Config\ContextNamespaceParser.cs" />
<Compile Include="Objects\Factory\Support\AssemblyScanningExtensionMethods.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Context\Config\spring-context-1.3.xsd">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\Spring.Aop\Spring.Aop.2010.csproj">
<Project>{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}</Project>
<Name>Spring.Aop.2010</Name>
</ProjectReference>
<ProjectReference Include="..\Spring.Core\Spring.Core.2010.csproj">
<Project>{710961A3-0DF4-49E4-A26E-F5B9C044AC84}</Project>
<Name>Spring.Core.2010</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@@ -1,101 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using Spring.Util;
namespace Spring.Context.Attributes
{
[TestFixture]
public class AssemblyTypeScannerTests
{
private class Scanner : AssemblyTypeScanner
{
public Scanner(string folderScanPath)
: base(folderScanPath)
{ }
public Scanner()
: base(null)
{ }
}
private Scanner _scanner;
private List<Predicate<Type>> _excludePredicates
{
get
{
//get at the collection of excludePredicates from the private field
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
return (List<Predicate<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_excludePredicates"));
}
}
private List<Predicate<Type>> _includePredicates
{
get
{
//get at the collection of includePredicates from the private field
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
return (List<Predicate<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_includePredicates"));
}
}
private List<IEnumerable<Type>> _typeSources
{
get
{
//get at the collection of typeSources from the private field
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
return (List<IEnumerable<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_typeSources"));
}
}
[SetUp]
public void _TestSetup()
{
_scanner = new Scanner();
}
[Test]
public void AssemblyHavingType_T_Adds_Assembly()
{
_scanner.AssemblyHavingType<Spring.Core.IOrdered>();
Assert.That(_typeSources.Any(t => t.Contains(typeof(Spring.Core.IOrdered))));
}
[Test]
public void IncludeType_T_Adds_Type()
{
_scanner.IncludeType<Spring.Core.IOrdered>();
_scanner.IncludeType<Spring.Core.IPriorityOrdered>();
_includePredicates.Any(p => p(typeof(Spring.Core.IOrdered)));
_includePredicates.Any(p => p(typeof(Spring.Core.IPriorityOrdered)));
}
[Test]
public void WithExcludeFilter_Excludes_Type()
{
_scanner.IncludeType<TheConfigurationClass>();
_scanner.IncludeType<TheImportedConfigurationClass>();
_scanner.WithExcludeFilter(t => t.Name.StartsWith("TheImported"));
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheConfigurationClass))));
Assert.False(_scanner.Scan().Contains(typeof(TheImportedConfigurationClass)));
}
[Test]
public void WithIncludeFilter_Includes_Types()
{
_scanner.WithIncludeFilter(t => t.Name.Contains("ConfigurationClass"));
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheConfigurationClass))));
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheImportedConfigurationClass))));
}
}
}

View File

@@ -1,223 +0,0 @@
using System;
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.Attributes
{
[TestFixture]
public class ConfigurationClassPostProcessorTests
{
private GenericApplicationContext _ctx;
[SetUp]
public void _SetUp()
{
_ctx = new GenericApplicationContext();
var configDefinitionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
_ctx.RegisterObjectDefinition(configDefinitionBuilder.ObjectDefinition.ObjectTypeName, configDefinitionBuilder.ObjectDefinition);
var postProcessorDefintionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
_ctx.RegisterObjectDefinition(postProcessorDefintionBuilder.ObjectDefinition.ObjectTypeName, postProcessorDefintionBuilder.ObjectDefinition);
Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(2));
_ctx.Refresh();
}
[Test]
public void Can_Assign_Init_And_Destroy_Methods()
{
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_Import_Configurations_From_Additional_Classes()
{
Assert.That(_ctx.GetObject(typeof(AnImportedType).Name), Is.Not.Null);
}
[Test]
public void Can_Respect_Assigned_Aliases()
{
var firstObject = _ctx["TheFirstAlias"];
var secondObject = _ctx["TheSecondAlias"];
Assert.That(firstObject, Is.InstanceOf<ObjectWithAnAlias>());
Assert.That(secondObject, Is.InstanceOf<ObjectWithAnAlias>());
}
[Test]
public void Can_Respect_Assigned_Name()
{
var result = _ctx["TheName"];
Assert.That(result, Is.InstanceOf<SingleNamedObject>());
}
[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));
}
[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<SingletonParent>());
Assert.That(_ctx[typeof(PrototypeChild).Name], Is.TypeOf<PrototypeChild>());
}
[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()
{
return new PrototypeChild();
}
[Definition]
public virtual SingletonParent SingletonParent()
{
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;
public SingletonParent(PrototypeChild child)
{
_child = child;
}
public PrototypeChild Child
{
get
{
return _child;
}
}
}
public class PrototypeChild { }
}

View File

@@ -1,38 +0,0 @@
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"));
}
}
}

View File

@@ -1,48 +0,0 @@
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(Object);// <--need to use *anything* ensured *not* to implement IObjectDefinitionReader
Assert.Fail("Expected Exception of type ArgumentException not thrown!");
}
catch (ArgumentException)
{
//swallow the expected exception
}
}
}
}

View File

@@ -1,5 +0,0 @@
<?xml version="1.0" encoding="utf-8" ?>
<objects xmlns="http://www.springframework.net">
<object id="xmlRegisteredObject" type="Spring.Context.Attributes.TypeRegisteredInXml, Spring.Core.Configuration.Tests" />
</objects>

View File

@@ -1,104 +0,0 @@
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;
using Spring.Context.Attributes;
namespace Spring.Objects.Factory.Support
{
[TestFixture]
public class AssemblyScanningExtensionMethodsTests
{
private GenericApplicationContext _context;
[SetUp]
public void _TestSetup()
{
_context = new GenericApplicationContext();
}
[Test]
public void Can_Filter_For_Assembly_Based_On_Assembly_Metadata()
{
_context.Scan(a => a.GetName().Name.StartsWith("Spring.Core.Configuration."));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Filter_For_Assembly_Containing_Specific_Type_But_Having_NO_Definitions()
{
//specifically filter assemblies for one that we *know* will result in NO [Configuration] types in it
_context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(Spring.Core.IOrdered).Name)));
_context.Refresh();
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(0));
}
[Test]
public void Can_Filter_For_Assembly_Containing_Specific_Type()
{
_context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Filter_For_Specific_Type()
{
_context.Scan(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name));
_context.Refresh();
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(4));
}
[Test]
public void Can_Filter_For_Specific_Types_With_Compound_Predicate()
{
_context.Scan(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name) || ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Filter_For_Specific_Types_With_Multiple_Include_Filters()
{
var scanner = new AssemblyObjectDefinitionScanner();
scanner.WithIncludeFilter(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name));
scanner.WithIncludeFilter(type => ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
_context.Scan(scanner);
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
[Test]
public void Can_Perform_Scan_With_No_Filtering()
{
_context.Scan();
_context.Refresh();
AssertExpectedObjectsAreRegisteredWith(_context);
}
private void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext _context)
{
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(13));
}
}
public class MarkerTypeForScannerToFind
{
}
}

View File

@@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Spring.Core.Configuration.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Microsoft")]
[assembly: AssemblyProduct("Spring.Core.Configuration.Tests")]
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("65e12092-0586-435f-b9ef-e4a35c302bef")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

View File

@@ -1,85 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProductVersion>8.0.30703</ProductVersion>
<SchemaVersion>2.0</SchemaVersion>
<ProjectGuid>{4F1A206C-09A8-43FF-B791-FE956E99A120}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Spring</RootNamespace>
<AssemblyName>Spring.Core.Configuration.Tests</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="nunit.framework, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<HintPath>..\..\..\lib\Net\2.0\nunit.framework.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Data" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Context\Attributes\AssemblyTypeScannerTests.cs" />
<Compile Include="Context\Attributes\ConfigurationClassPostProcessorTests.cs" />
<Compile Include="Context\Attributes\DefinitionAttributeTests.cs" />
<Compile Include="Context\Attributes\ImportResourceAttributeTests.cs" />
<Compile Include="Context\Config\ContextNamespaceParserTests.cs" />
<Compile Include="Objects\Factory\Support\AssemblyScanningExtensionMethodsTests.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\src\Spring\Spring.Aop\Spring.Aop.2010.csproj">
<Project>{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}</Project>
<Name>Spring.Aop.2010</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Spring\Spring.Core.Configuration\Spring.Core.Configuration.2010.csproj">
<Project>{7B65D538-E863-4F57-8DDC-2C38E4150045}</Project>
<Name>Spring.Core.Configuration.2010</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\src\Spring\Spring.Core\Spring.Core.2010.csproj">
<Project>{710961A3-0DF4-49E4-A26E-F5B9C044AC84}</Project>
<Name>Spring.Core.2010</Name>
</ProjectReference>
<ProjectReference Include="..\Spring.Core.Tests\Spring.Core.Tests.2010.csproj">
<Project>{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}</Project>
<Name>Spring.Core.Tests.2010</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Context\Attributes\ObjectDefinitions.xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Context\Config\ContextNamespaceParserTests.xml">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>