SPRNET-1536 merge code and tests from SPRNET-CODECONFIG project
This commit is contained in:
@@ -0,0 +1,189 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using System.Reflection;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Stereotype;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// AssemblyTypeScanner that only accepts types that also meet the requirements of being ObjectDefintions.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AssemblyObjectDefinitionScanner : RequiredConstraintAssemblyTypeScanner
|
||||
{
|
||||
private readonly List<Predicate<Assembly>> _assemblyExclusionPredicates = new List<Predicate<Assembly>>();
|
||||
|
||||
private readonly IList<string> _springAssemblies = new List<string>()
|
||||
{
|
||||
"Spring.Core",
|
||||
"Spring.Core.Configuration",
|
||||
"Spring.Aop",
|
||||
"Spring.Data",
|
||||
"Spring.Services",
|
||||
"Spring.Messaging",
|
||||
"Spring.Messaging.Ems",
|
||||
"Spring.Messaging.Nms",
|
||||
"Spring.Template.Velocity",
|
||||
"Spring.Messaging.Quartz",
|
||||
"Spring.Testing.Microsoft",
|
||||
"Spring.Testing.Nunit",
|
||||
"Spring.Data.NHibernate12",
|
||||
"Spring.Data.NHibernate21",
|
||||
"Spring.Data.NHibernate20",
|
||||
"Spring.Data.NHibernate30",
|
||||
"Spring.Web",
|
||||
"Spring.Web.Extensions",
|
||||
"Spring.Web.Mvc",
|
||||
};
|
||||
|
||||
private IObjectNameGenerator _objectNameGenerator = new AttributeObjectNameGenerator();
|
||||
|
||||
/// <summary>
|
||||
/// Provides the name generator for all scanned objects.
|
||||
/// Default is <see cref="AttributeObjectNameGenerator"/>
|
||||
/// </summary>
|
||||
public IObjectNameGenerator ObjectNameGenerator
|
||||
{
|
||||
get { return _objectNameGenerator; }
|
||||
set { _objectNameGenerator = value; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the defintions for types.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry.</param>
|
||||
/// <param name="typesToRegister">The types to register.</param>
|
||||
private void RegisterDefinitionsForTypes(IObjectDefinitionRegistry registry, IEnumerable<Type> typesToRegister)
|
||||
{
|
||||
foreach (Type type in typesToRegister)
|
||||
{
|
||||
var definition = new ScannedGenericObjectDefinition(type, Defaults);
|
||||
string objectName = ObjectNameGenerator.GenerateObjectName(definition, registry);
|
||||
registry.RegisterObjectDefinition(objectName, definition);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Applies the assembly filters to the assembly candidates.
|
||||
/// </summary>
|
||||
/// <param name="assemblyCandidates">The assembly candidates.</param>
|
||||
/// <returns></returns>
|
||||
protected override IEnumerable<Assembly> ApplyAssemblyFiltersTo(IEnumerable<Assembly> assemblyCandidates)
|
||||
{
|
||||
return assemblyCandidates.Where(
|
||||
delegate(Assembly candidate) { return IsIncludedAssembly(candidate) && !IsExcludedAssembly(candidate); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified candidate is and excluded assembly.
|
||||
/// </summary>
|
||||
/// <param name="candidate">The candidate.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified candidate is an excluded assembly ; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected virtual bool IsExcludedAssembly(Assembly candidate)
|
||||
{
|
||||
return _assemblyExclusionPredicates.Any(delegate(Predicate<Assembly> exclude) { return exclude(candidate); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the required constraint is satisfied by the specified type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the required constraint is satisfied by the specified type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected override bool IsRequiredConstraintSatisfiedBy(Type type)
|
||||
{
|
||||
if (!type.Assembly.ReflectionOnly)
|
||||
{
|
||||
try
|
||||
{
|
||||
return Attribute.GetCustomAttribute(type, typeof(ComponentAttribute), true) != null &&
|
||||
!type.IsAbstract;
|
||||
}
|
||||
catch (AmbiguousMatchException)
|
||||
{
|
||||
Logger.Error(m => m("Type {0} has more than one ComponentAttributes assigned to it.", type.FullName));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool satisfied = false;
|
||||
|
||||
foreach (CustomAttributeData customAttributeData in CustomAttributeData.GetCustomAttributes(type))
|
||||
{
|
||||
if (customAttributeData.Constructor.DeclaringType.FullName == typeof(ComponentAttribute).FullName &&
|
||||
!type.IsAbstract)
|
||||
{
|
||||
satisfied = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return satisfied;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default filters.
|
||||
/// </summary>
|
||||
protected override void SetDefaultFilters()
|
||||
{
|
||||
//set the built-in defaults
|
||||
base.SetDefaultFilters();
|
||||
|
||||
//add the desired assembly exclusions to the list
|
||||
_assemblyExclusionPredicates.Add(
|
||||
delegate(Assembly a) { return _springAssemblies.Contains(a.GetName().Name); });
|
||||
_assemblyExclusionPredicates.Add(delegate(Assembly a) { return a.GetName().Name.StartsWith("System."); });
|
||||
_assemblyExclusionPredicates.Add(delegate(Assembly a) { return a.GetName().Name.StartsWith("Microsoft."); });
|
||||
_assemblyExclusionPredicates.Add(delegate(Assembly a) { return a.GetName().Name == "mscorlib"; });
|
||||
_assemblyExclusionPredicates.Add(delegate(Assembly a) { return a.GetName().Name == "System"; });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans the and register types.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry within which to register the types.</param>
|
||||
public virtual void ScanAndRegisterTypes(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
IEnumerable<Type> configTypes = base.Scan();
|
||||
RegisterDefinitionsForTypes(registry, configTypes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AssemblyObjectDefinitionScanner"/> class.
|
||||
/// </summary>
|
||||
public AssemblyObjectDefinitionScanner()
|
||||
{
|
||||
AssemblyLoadExclusionPredicates.Add(delegate(string name) { return _springAssemblies.Contains(name); });
|
||||
AssemblyLoadExclusionPredicates.Add(delegate(string name) { return name.StartsWith("System."); });
|
||||
AssemblyLoadExclusionPredicates.Add(delegate(string name) { return name.StartsWith("Microsoft."); });
|
||||
AssemblyLoadExclusionPredicates.Add(delegate(string name) { return name == "mscorlib"; });
|
||||
AssemblyLoadExclusionPredicates.Add(delegate(string name) { return name == "System"; });
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
400
src/Spring/Spring.Core/Context/Attributes/AssemblyTypeScanner.cs
Normal file
400
src/Spring/Spring.Core/Context/Attributes/AssemblyTypeScanner.cs
Normal file
@@ -0,0 +1,400 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using Common.Logging;
|
||||
using Spring.Context.Attributes.TypeFilters;
|
||||
using Spring.Util;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Scans Assebmlies for Types that satisfy a given set of constraints.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class AssemblyTypeScanner : IAssemblyTypeScanner
|
||||
{
|
||||
/// <summary>
|
||||
/// Logger Instance.
|
||||
/// </summary>
|
||||
protected static readonly ILog Logger = LogManager.GetLogger<AssemblyTypeScanner>();
|
||||
|
||||
/// <summary>
|
||||
/// Names of Assemblies to exclude from being loaded for scanning.
|
||||
/// </summary>
|
||||
protected IList<Predicate<string>> AssemblyLoadExclusionPredicates = new List<Predicate<string>>();
|
||||
|
||||
/// <summary>
|
||||
/// Assembly Inclusion Predicates.
|
||||
/// </summary>
|
||||
protected readonly List<Predicate<Assembly>> AssemblyInclusionPredicates = new List<Predicate<Assembly>>();
|
||||
|
||||
/// <summary>
|
||||
/// Type Exclusion Predicates.
|
||||
/// </summary>
|
||||
protected readonly List<Predicate<Type>> TypeExclusionPredicates = new List<Predicate<Type>>();
|
||||
|
||||
/// <summary>
|
||||
/// Type Exclusion Predicates.
|
||||
/// </summary>
|
||||
protected readonly List<ITypeFilter> TypeExclusionTypeFilters = new List<ITypeFilter>();
|
||||
|
||||
/// <summary>
|
||||
/// Type Inclusion Predicates.
|
||||
/// </summary>
|
||||
protected readonly List<Predicate<Type>> TypeInclusionPredicates = new List<Predicate<Type>>();
|
||||
|
||||
/// <summary>
|
||||
/// Type Inclusion TypeFilters.
|
||||
/// </summary>
|
||||
protected readonly List<ITypeFilter> TypeInclusionTypeFilter = new List<ITypeFilter>();
|
||||
|
||||
/// <summary>
|
||||
/// Assemblies to scan.
|
||||
/// </summary>
|
||||
protected readonly List<IEnumerable<Type>> TypeSources = new List<IEnumerable<Type>>();
|
||||
|
||||
/// <summary>
|
||||
/// Stores the object default definitons defined in the XML configuration documnet
|
||||
/// </summary>
|
||||
protected DocumentDefaultsDefinition _defaults;
|
||||
|
||||
/// <summary>
|
||||
/// Stores the object default definitons defined in the XML configuration documnet
|
||||
/// </summary>
|
||||
public DocumentDefaultsDefinition Defaults { get { return _defaults; } set { _defaults = value; } }
|
||||
|
||||
#region IAssemblyTypeScanner Members
|
||||
|
||||
/// <summary>
|
||||
/// Assemblies the type of the having.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner AssemblyHavingType<T>()
|
||||
{
|
||||
TypeSources.Add(new AssemblyTypeSource((typeof(T).Assembly)));
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Excludes the type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner ExcludeType<T>()
|
||||
{
|
||||
TypeExclusionPredicates.Add(delegate(Type t) { return t.FullName == typeof(T).FullName; });
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Includes the type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner IncludeType<T>()
|
||||
{
|
||||
TypeInclusionPredicates.Add(delegate(Type t) { return t.FullName == typeof(T).FullName; });
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Includes the types.
|
||||
/// </summary>
|
||||
/// <param name="typeSource">The type source.</param>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(typeSource, "typeSource");
|
||||
TypeSources.Add(typeSource);
|
||||
TypeInclusionPredicates.Add(
|
||||
delegate(Type t) { return typeSource.Any(delegate(Type t1) { return t1.FullName == t.FullName; }); });
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Performs the Scan, respecting all filter settings.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
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 (IsCompoundPredicateSatisfiedBy(type))
|
||||
{
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the assembly filter.
|
||||
/// </summary>
|
||||
/// <param name="assemblyPredicate">The assembly predicate.</param>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate)
|
||||
{
|
||||
AssemblyInclusionPredicates.Add(assemblyPredicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the exclude filter.
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate.</param>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate)
|
||||
{
|
||||
TypeExclusionPredicates.Add(predicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the exclude filter.
|
||||
/// </summary>
|
||||
/// <param name="filter">The type filter.</param>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner WithExcludeFilter(ITypeFilter filter)
|
||||
{
|
||||
if (filter != null)
|
||||
TypeExclusionTypeFilters.Add(filter);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the include filter.
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate.</param>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate)
|
||||
{
|
||||
TypeInclusionPredicates.Add(predicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the include filter.
|
||||
/// </summary>
|
||||
/// <param name="filter">The filter type.</param>
|
||||
/// <returns></returns>
|
||||
public IAssemblyTypeScanner WithIncludeFilter(ITypeFilter filter)
|
||||
{
|
||||
if (filter != null)
|
||||
TypeInclusionTypeFilter.Add(filter);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private List<string> GetAllAssembliesInPath()
|
||||
{
|
||||
|
||||
string folderPath = GetCurrentBinDirectoryPath();
|
||||
|
||||
var assemblies = new List<string>();
|
||||
assemblies.AddRange(DiscoverAssemblies(folderPath, "*.dll"));
|
||||
assemblies.AddRange(DiscoverAssemblies(folderPath, "*.exe"));
|
||||
|
||||
Logger.Debug(m => m("Assemblies to be scanned: {0}", StringUtils.ArrayToCommaDelimitedString(assemblies.ToArray())));
|
||||
|
||||
return assemblies;
|
||||
}
|
||||
|
||||
private IEnumerable<Assembly> GetAllMatchingAssemblies()
|
||||
{
|
||||
IEnumerable<string> assemblyCandidates = GetAllAssembliesInPath();
|
||||
|
||||
IList<Assembly> assemblies = new List<Assembly>();
|
||||
|
||||
foreach (string assembly in assemblyCandidates)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(assembly))
|
||||
{
|
||||
Assembly loadedAssembly = TryLoadAssemblyFromPath(assembly);
|
||||
|
||||
if (null != loadedAssembly)
|
||||
{
|
||||
assemblies.Add(loadedAssembly);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ApplyAssemblyFiltersTo(assemblies);
|
||||
}
|
||||
|
||||
private Assembly TryLoadAssemblyFromPath(string filename)
|
||||
{
|
||||
Assembly assembly = null;
|
||||
|
||||
try
|
||||
{
|
||||
assembly = Assembly.LoadFrom(filename);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//log and swallow everything that might go wrong here...
|
||||
Logger.Debug(m => m("Failed to load assembly {0} to inspect for [Configuration] types!", filename), ex);
|
||||
}
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
private string GetCurrentBinDirectoryPath()
|
||||
{
|
||||
return string.IsNullOrEmpty(AppDomain.CurrentDomain.DynamicDirectory)
|
||||
? AppDomain.CurrentDomain.BaseDirectory
|
||||
: AppDomain.CurrentDomain.DynamicDirectory;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Applies the assembly filters to the assembly candidates.
|
||||
/// </summary>
|
||||
/// <param name="assemblyCandidates">The assembly candidates.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual IEnumerable<Assembly> ApplyAssemblyFiltersTo(IEnumerable<Assembly> assemblyCandidates)
|
||||
{
|
||||
return
|
||||
assemblyCandidates.Where(IsIncludedAssembly).
|
||||
AsEnumerable();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the compound predicate is satisfied by the specified type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the compound predicate is satisfied by the specified type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected abstract bool IsCompoundPredicateSatisfiedBy(Type type);
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is excluded type] [the specified type].
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is excluded type] [the specified type]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected virtual bool IsExcludedType(Type type)
|
||||
{
|
||||
if (TypeExclusionPredicates.Count > 0 && TypeExclusionPredicates.Any(delegate(Predicate<Type> exclude) { return exclude(type); }))
|
||||
return true;
|
||||
|
||||
foreach(var filter in TypeExclusionTypeFilters)
|
||||
{
|
||||
if (filter.Match(type))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is included assembly] [the specified assembly].
|
||||
/// </summary>
|
||||
/// <param name="assembly">The assembly.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is included assembly] [the specified assembly]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected virtual bool IsIncludedAssembly(Assembly assembly)
|
||||
{
|
||||
return AssemblyInclusionPredicates.Any(delegate(Predicate<Assembly> include) { return include(assembly); });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether [is included type] [the specified type].
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if [is included type] [the specified type]; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected virtual bool IsIncludedType(Type type)
|
||||
{
|
||||
if (TypeInclusionPredicates.Count > 0 && TypeInclusionPredicates.Any(delegate(Predicate<Type> include) { return include(type); }))
|
||||
return true;
|
||||
|
||||
foreach(var filter in TypeInclusionTypeFilter)
|
||||
{
|
||||
if (filter.Match(type))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default filters.
|
||||
/// </summary>
|
||||
protected virtual void SetDefaultFilters()
|
||||
{
|
||||
if (TypeInclusionPredicates.Count == 0 && TypeInclusionTypeFilter.Count == 0)
|
||||
TypeInclusionPredicates.Add(delegate { return true; });
|
||||
|
||||
if (TypeExclusionPredicates.Count == 0 && TypeExclusionTypeFilters.Count == 0)
|
||||
TypeExclusionPredicates.Add(delegate { return false; });
|
||||
|
||||
if (AssemblyInclusionPredicates.Count == 0)
|
||||
AssemblyInclusionPredicates.Add(delegate { return true; });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the assemblies found.
|
||||
/// </summary>
|
||||
/// <param name="folderPath">The folder path.</param>
|
||||
/// <param name="extension">The extension.</param>
|
||||
private IList<string> DiscoverAssemblies(string folderPath, string extension)
|
||||
{
|
||||
IList<string> assemblies = new List<string>();
|
||||
|
||||
IEnumerable<string> files = Directory.GetFiles(folderPath, extension, SearchOption.AllDirectories);
|
||||
|
||||
foreach (string file in files)
|
||||
{
|
||||
string name = Path.GetFileNameWithoutExtension(file);
|
||||
|
||||
if (!AssemblyLoadExclusionPredicates.Any(delegate(Predicate<string> exclude) { return exclude(name); }))
|
||||
{
|
||||
assemblies.Add(file);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return assemblies;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,63 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a collection of Types.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public class AssemblyTypeSource : IEnumerable<Type>
|
||||
{
|
||||
private readonly _Assembly _assembly;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="AssemblyTypeSource"/> class.
|
||||
/// </summary>
|
||||
/// <param name="assembly">The assembly.</param>
|
||||
public AssemblyTypeSource(Assembly assembly)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(assembly, "assembly");
|
||||
this._assembly = assembly;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the enumerator.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public IEnumerator<Type> GetEnumerator()
|
||||
{
|
||||
foreach (var type in _assembly.GetTypes())
|
||||
yield return type;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 Spring.Objects.Factory.Attributes;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Utility class that allows for convenient registration of common <see cref="IObjectPostProcessor"/>
|
||||
/// and <see cref="IObjectFactoryPostProcessor"/> definitions for attribute based configuration
|
||||
/// </summary>
|
||||
/// <seealso cref="ConfigurationClassObjectDefinitionReader"/>
|
||||
/// <seealso cref="RequiredAttributeObjectPostProcessor"/>
|
||||
///
|
||||
/// <author>Mark Pollack (.NET)</author>
|
||||
/// <author>Mark Fisher</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Chris Beams</author>
|
||||
public class AttributeConfigUtils
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// The object name of the internally managed Configuration attribute processor.
|
||||
/// </summary>
|
||||
public static readonly string CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME =
|
||||
"Spring.Context.Attributes.InternalConfigurationClassPostProcessor";
|
||||
|
||||
/// <summary>
|
||||
/// The object name of the internally managed Autowire attribute processor
|
||||
/// </summary>
|
||||
public static readonly string AUTOWIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME =
|
||||
"Spring.Context.Attributes.InternalAutowiredClassPostProcessor";
|
||||
|
||||
/// <summary>
|
||||
///The object name of the internally managed Required attribute processor.
|
||||
/// </summary>
|
||||
public static readonly string REQUIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME =
|
||||
"Spring.Context.Attributes.InternalRequiredClassPostProcessor";
|
||||
|
||||
/// <summary>
|
||||
///The object name of the internally managed InitDestroy attribute processor.
|
||||
/// </summary>
|
||||
public static readonly string INITDESTROY_ATTRIBUTE_PROCESSOR_OBJECT_NAME =
|
||||
"Spring.Context.Attributes.InternalInitDestroyClassPostProcessor";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registers the attribute config processors.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry.</param>
|
||||
public static void RegisterAttributeConfigProcessors(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
if (!registry.ContainsObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
|
||||
{
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(typeof(ConfigurationClassPostProcessor));
|
||||
RegisterPostProcessor(registry, objectDefinition, CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME);
|
||||
}
|
||||
|
||||
if (!registry.ContainsObjectDefinition(AUTOWIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
|
||||
{
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(typeof(AutowiredAttributeObjectPostProcessor));
|
||||
RegisterPostProcessor(registry, objectDefinition, AUTOWIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME);
|
||||
}
|
||||
|
||||
if (!registry.ContainsObjectDefinition(REQUIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
|
||||
{
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(typeof(RequiredAttributeObjectPostProcessor));
|
||||
RegisterPostProcessor(registry, objectDefinition, REQUIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME);
|
||||
}
|
||||
|
||||
if (!registry.ContainsObjectDefinition(INITDESTROY_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
|
||||
{
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(typeof(InitDestroyAttributeObjectPostProcessor));
|
||||
RegisterPostProcessor(registry, objectDefinition, INITDESTROY_ATTRIBUTE_PROCESSOR_OBJECT_NAME);
|
||||
}
|
||||
}
|
||||
|
||||
private static void RegisterPostProcessor(IObjectDefinitionRegistry registry, IConfigurableObjectDefinition objectDefinition, string objectName)
|
||||
{
|
||||
objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
registry.RegisterObjectDefinition(objectName, objectDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
#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 Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Default Name Generator for attribute driven component scan.
|
||||
///
|
||||
/// First choice is the provided name of the Component attribute.
|
||||
/// Fallback is the short type name.
|
||||
/// </summary>
|
||||
public class AttributeObjectNameGenerator : IObjectNameGenerator
|
||||
{
|
||||
/// <summary>
|
||||
/// Generates an object name for the given object definition.
|
||||
/// </summary>
|
||||
/// <param name="definition">The object definition to generate a name for.</param>
|
||||
/// <param name="registry">The object definitions registry that the given definition is
|
||||
/// supposed to be registerd with</param>
|
||||
/// <returns>
|
||||
/// the generated object name
|
||||
/// </returns>
|
||||
public string GenerateObjectName(IObjectDefinition definition, IObjectDefinitionRegistry registry)
|
||||
{
|
||||
if (definition is ScannedGenericObjectDefinition)
|
||||
{
|
||||
string objectName = ((ScannedGenericObjectDefinition) definition).ComponentName;
|
||||
if (!string.IsNullOrEmpty(objectName))
|
||||
return objectName;
|
||||
}
|
||||
return BuildDefaultObjectName(definition);
|
||||
}
|
||||
|
||||
private string BuildDefaultObjectName(IObjectDefinition definition)
|
||||
{
|
||||
return definition.ObjectType.FullName;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Stereotype;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a class declares one or more <see cref="ObjectDefAttribute"/> 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 <see cref="ComponentAttribute"/>, therefore Configuration
|
||||
/// classes are candidates for component-scanning.
|
||||
/// </para>
|
||||
/// <para>May be used in conjunction with the <see cref="LazyAttribute"/> 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-sealed</li>
|
||||
/// <li>Configuration classes must have a default/no-arg constructor</li>
|
||||
/// </ul>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ConfigurationAttribute : ComponentAttribute
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConfigurationAttribute class.
|
||||
/// </summary>
|
||||
public ConfigurationAttribute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Configuration class.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public ConfigurationAttribute(string name)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
252
src/Spring/Spring.Core/Context/Attributes/ConfigurationClass.cs
Normal file
252
src/Spring/Spring.Core/Context/Attributes/ConfigurationClass.cs
Normal file
@@ -0,0 +1,252 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using Spring.Core.IO;
|
||||
using Spring.Collections.Generic;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an instance of the metadata that has been parsed from a class with the <see cref="ConfigurationAttribute"/> applied to it.
|
||||
/// </summary>
|
||||
public class ConfigurationClass
|
||||
{
|
||||
private Type _configurationClassType;
|
||||
|
||||
private readonly IDictionary<string, Type> _importedResources = new Dictionary<string, Type>();
|
||||
|
||||
private readonly Collections.Generic.ISet<ConfigurationClassMethod> _methods = new HashedSet<ConfigurationClassMethod>();
|
||||
|
||||
private string _objectName;
|
||||
|
||||
private readonly 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)
|
||||
{
|
||||
_objectName = objectName;
|
||||
_configurationClassType = type;
|
||||
_resource = new ConfigurationClassAssemblyResource(type);
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the type of the configuration class.
|
||||
/// </summary>
|
||||
/// <value>The type of the configuration class.</value>
|
||||
public Type ConfigurationClassType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _configurationClassType;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the imported resources.
|
||||
/// </summary>
|
||||
/// <value>The imported resources.</value>
|
||||
public IDictionary<string, Type> ImportedResources
|
||||
{
|
||||
get
|
||||
{
|
||||
return _importedResources;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the methods.
|
||||
/// </summary>
|
||||
/// <value>The methods.</value>
|
||||
public Collections.Generic.ISet<ConfigurationClassMethod> Methods
|
||||
{
|
||||
get
|
||||
{
|
||||
return _methods;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the object.
|
||||
/// </summary>
|
||||
/// <value>The name of the object.</value>
|
||||
public string ObjectName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _objectName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_objectName = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource.
|
||||
/// </summary>
|
||||
/// <value>The resource.</value>
|
||||
public IResource Resource
|
||||
{
|
||||
get
|
||||
{
|
||||
return _resource;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the SimpleName of the object.
|
||||
/// </summary>
|
||||
/// <value>The simple name.</value>
|
||||
public string SimpleName
|
||||
{
|
||||
get { return ConfigurationClassType.Name; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds the imported resource.
|
||||
/// </summary>
|
||||
/// <param name="importedResource">The imported resource.</param>
|
||||
/// <param name="readerClass">The reader class capable of interpreting the imported resource.</param>
|
||||
public void AddImportedResource(string importedResource, Type readerClass)
|
||||
{
|
||||
_importedResources.Add(importedResource, readerClass);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
|
||||
/// </summary>
|
||||
/// <param name="other">The <see cref="System.Object"/> to compare with this instance.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
return this == other || (other is ConfigurationClass && ConfigurationClassType == ((ConfigurationClass)other).ConfigurationClassType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a hash code for this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A hash code for this instance, suitable for use in hashing algorithms and data structures like a hash table.
|
||||
/// </returns>
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ConfigurationClassType.GetHashCode() * 14;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the specified <see cref="ConfigurationClass"/> and reports all discovered violations to the provided problem reporter for appropriate action.
|
||||
/// </summary>
|
||||
/// <param name="problemReporter">The problem reporter.</param>
|
||||
public void Validate(IProblemReporter problemReporter)
|
||||
{
|
||||
// A [ObjectDef] method may only be overloaded through inheritance. No single
|
||||
// [Configuration] class may declare two [ObjectDef] methods with the same name.
|
||||
const 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 paramTypes = ParamTypesToString(method.MethodMetadata);
|
||||
|
||||
String fqMethodName = dClassName + hashDelim + methodName + paramTypes;
|
||||
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 string ParamTypesToString(MethodInfo methodMetadata)
|
||||
{
|
||||
var result = new StringBuilder();
|
||||
|
||||
foreach (var parameter in methodMetadata.GetParameters())
|
||||
{
|
||||
result.Append(parameter.ParameterType.ToString());
|
||||
}
|
||||
|
||||
return result.ToString();
|
||||
}
|
||||
|
||||
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))
|
||||
{ }
|
||||
|
||||
}
|
||||
|
||||
//This class is for future use when parameterized [ObjectDef] methods are supported in the future.
|
||||
//Until then, the test for only permitting zero-param [ObjectDef] methods would fail first, previnting this error from ever being reported
|
||||
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 [ObjectDef] method of a given name is allowed within each [Configuration] class.", configurationClassType.Name, count, methodName), new Location(resource, configurationClassType))
|
||||
{ }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,203 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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.IO;
|
||||
using System.Reflection;
|
||||
using Spring.Core.IO;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Implementation of the IResource that represents an assembly containing one or more <see cref="ConfigurationClass"/> resources.
|
||||
/// </summary>
|
||||
public class ConfigurationClassAssemblyResource : IResource
|
||||
{
|
||||
private readonly string _containingAssemblyFileName;
|
||||
private readonly Type _type;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:System.Object"/> class.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
public ConfigurationClassAssemblyResource(Type type)
|
||||
{
|
||||
_type = type;
|
||||
_containingAssemblyFileName = Assembly.GetAssembly(_type.GetType()).Location;
|
||||
}
|
||||
|
||||
#region IResource Members
|
||||
|
||||
/// <summary>
|
||||
/// Creates a resource relative to this resource.
|
||||
/// </summary>
|
||||
/// <param name="relativePath">The path (always resolved as relative to this resource).</param>
|
||||
/// <returns>The relative resource.</returns>
|
||||
/// <exception cref="T:System.IO.IOException">
|
||||
/// If the relative resource could not be created from the supplied
|
||||
/// path.
|
||||
/// </exception>
|
||||
/// <exception cref="T:System.NotSupportedException">
|
||||
/// If the resource does not support the notion of a relative path.
|
||||
/// </exception>
|
||||
public IResource CreateRelative(string relativePath)
|
||||
{
|
||||
throw new InvalidOperationException();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this resource represent a handle with an open stream?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this resource represents a handle with an
|
||||
/// open stream.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// If <see langword="true"/>, the <see cref="T:System.IO.Stream"/>
|
||||
/// cannot be read multiple times, and must be read and then closed to
|
||||
/// avoid resource leaks.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Will be <see langword="false"/> for all usual resource descriptors.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="P:Spring.Core.IO.IInputStreamSource.InputStream"/>
|
||||
public bool IsOpen
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the <see cref="T:System.Uri"/> handle for this resource.
|
||||
/// </summary>
|
||||
/// <value>The <see cref="T:System.Uri"/> handle for this resource.</value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// For safety, always check the value of the
|
||||
/// <see cref="P:Spring.Core.IO.IResource.Exists"/> property prior to
|
||||
/// accessing this property; resources that cannot be exposed as
|
||||
/// a <see cref="T:System.Uri"/> will typically return
|
||||
/// <see langword="false"/> from a call to the
|
||||
/// <see cref="P:Spring.Core.IO.IResource.Exists"/> property.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="T:System.IO.IOException">
|
||||
/// If the resource is not available or cannot be exposed as a
|
||||
/// <see cref="T:System.Uri"/>.
|
||||
/// </exception>
|
||||
/// <seealso cref="T:Spring.Core.IO.IResource"/>
|
||||
/// <seealso cref="P:Spring.Core.IO.IResource.Exists"/>
|
||||
public Uri Uri
|
||||
{
|
||||
get { return new Uri(_containingAssemblyFileName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="T:System.IO.FileInfo"/> handle for this resource.
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// The <see cref="T:System.IO.FileInfo"/> handle for this resource.
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// For safety, always check the value of the
|
||||
/// <see cref="P:Spring.Core.IO.IResource.Exists"/> property prior to
|
||||
/// accessing this property; resources that cannot be exposed as
|
||||
/// a <see cref="T:System.IO.FileInfo"/> will typically return
|
||||
/// <see langword="false"/> from a call to the
|
||||
/// <see cref="P:Spring.Core.IO.IResource.Exists"/> property.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <exception cref="T:System.IO.IOException">
|
||||
/// If the resource is not available on a filesystem, or cannot be
|
||||
/// exposed as a <see cref="T:System.IO.FileInfo"/> handle.
|
||||
/// </exception>
|
||||
/// <seealso cref="T:Spring.Core.IO.IResource"/>
|
||||
/// <seealso cref="P:Spring.Core.IO.IResource.Exists"/>
|
||||
public FileInfo File
|
||||
{
|
||||
get { return new FileInfo(_containingAssemblyFileName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a description for this resource.
|
||||
/// </summary>
|
||||
/// <value>A description for this resource.</value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// The description is typically used for diagnostics and other such
|
||||
/// logging when working with the resource.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Implementations are also encouraged to return this value from their
|
||||
/// <see cref="M:System.Object.ToString"/> method.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public string Description
|
||||
{
|
||||
get { return _type.FullName; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Does this resource actually exist in physical form?
|
||||
/// </summary>
|
||||
/// <value>
|
||||
/// <see langword="true"/> if this resource actually exists in physical
|
||||
/// form (for example on a filesystem).
|
||||
/// </value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// An example of a resource that physically exists would be a
|
||||
/// file on a local filesystem. An example of a resource that does not
|
||||
/// physically exist would be an in-memory stream.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <seealso cref="P:Spring.Core.IO.IResource.File"/>
|
||||
/// <seealso cref="P:Spring.Core.IO.IResource.Uri"/>
|
||||
public bool Exists
|
||||
{
|
||||
get { return System.IO.File.Exists(_containingAssemblyFileName); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return an <see cref="T:System.IO.Stream"/> for this resource.
|
||||
/// </summary>
|
||||
/// <value>An <see cref="T:System.IO.Stream"/>.</value>
|
||||
/// <remarks>
|
||||
/// <note type="caution">
|
||||
/// Clients of this interface must be aware that every access of this
|
||||
/// property will create a <i>fresh</i>
|
||||
/// <see cref="T:System.IO.Stream"/>;
|
||||
/// it is the responsibility of the calling code to close any such
|
||||
/// <see cref="T:System.IO.Stream"/>.
|
||||
/// </note>
|
||||
/// </remarks>
|
||||
/// <exception cref="T:System.IO.IOException">
|
||||
/// If the stream could not be opened.
|
||||
/// </exception>
|
||||
public Stream InputStream
|
||||
{
|
||||
get { throw new InvalidOperationException(); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Reflection;
|
||||
using System.Reflection.Emit;
|
||||
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Util;
|
||||
using Spring.Proxy;
|
||||
using Common.Logging;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Enhances Configuration classes by generating a dynamic proxy capable of
|
||||
/// interacting with the Spring container to respect object semantics.
|
||||
/// </summary>
|
||||
/// <author>Chris Beams</author>
|
||||
/// <author>Juergen Hoeller</author>
|
||||
/// <author>Bruno Baia (.NET)</author>
|
||||
/// <seealso cref="ConfigurationClassPostProcessor"/>
|
||||
public class ConfigurationClassEnhancer
|
||||
{
|
||||
private IConfigurationClassInterceptor interceptor;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="ConfigurationClassEnhancer"/> class.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory">
|
||||
/// The supplied ObjectFactory to check for the existence of object definitions.
|
||||
/// </param>
|
||||
public ConfigurationClassEnhancer(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(objectFactory, "objectFactory");
|
||||
|
||||
this.interceptor = new ConfigurationClassInterceptor(objectFactory);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generates a dynamic subclass of the specified Configuration class with a
|
||||
/// container-aware interceptor capable of respecting scoping and other bean semantics.
|
||||
/// </summary>
|
||||
/// <param name="configClass">The Configuration class.</param>
|
||||
/// <returns>The enhanced subclass.</returns>
|
||||
public Type Enhance(Type configClass)
|
||||
{
|
||||
ConfigurationClassProxyTypeBuilder proxyTypeBuilder = new ConfigurationClassProxyTypeBuilder(configClass, this.interceptor);
|
||||
return proxyTypeBuilder.BuildProxyType();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Intercepts the invocation of any <see cref="ObjectDefAttribute"/>-decorated methods in order
|
||||
/// to ensure proper handling of object semantics such as scoping and AOP proxying.
|
||||
/// </summary>
|
||||
public interface IConfigurationClassInterceptor
|
||||
{
|
||||
/// <summary>
|
||||
/// Process the <see cref="ObjectDefAttribute"/>-decorated method to check
|
||||
/// for the existence of this object.
|
||||
/// </summary>
|
||||
/// <param name="method">The method providing the object definition.</param>
|
||||
/// <param name="instance">When this method returns true, contains the object definition.</param>
|
||||
/// <returns>true if the object exists; otherwise, false.</returns>
|
||||
bool ProcessDefinition(MethodInfo method, out object instance);
|
||||
}
|
||||
|
||||
private sealed class ConfigurationClassInterceptor : IConfigurationClassInterceptor
|
||||
{
|
||||
#region Logging
|
||||
|
||||
private static readonly ILog Logger = LogManager.GetLogger<ConfigurationClassInterceptor>();
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly IConfigurableListableObjectFactory _configurableListableObjectFactory;
|
||||
|
||||
public ConfigurationClassInterceptor(IConfigurableListableObjectFactory configurableListableObjectFactory)
|
||||
{
|
||||
this._configurableListableObjectFactory = configurableListableObjectFactory;
|
||||
}
|
||||
|
||||
public bool ProcessDefinition(MethodInfo method, out object instance)
|
||||
{
|
||||
instance = null;
|
||||
|
||||
string objectName = method.Name;
|
||||
|
||||
if (objectName.StartsWith("set_") || objectName.StartsWith("get_"))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
object[] attribs = method.GetCustomAttributes(typeof(ObjectDefAttribute), true);
|
||||
if (attribs.Length == 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (this._configurableListableObjectFactory.IsCurrentlyInCreation(objectName))
|
||||
{
|
||||
Logger.Debug(m => m("Object '{0}' currently in creation, created one", objectName));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
Logger.Debug(m => m("Object '{0}' not in creation, asked the application context for one", objectName));
|
||||
|
||||
instance = this._configurableListableObjectFactory.GetObject(objectName);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
#region Proxy builder classes definition
|
||||
|
||||
private sealed class ConfigurationClassProxyTypeBuilder : InheritanceProxyTypeBuilder
|
||||
{
|
||||
private FieldBuilder interceptorField;
|
||||
private IConfigurationClassInterceptor interceptor;
|
||||
|
||||
public ConfigurationClassProxyTypeBuilder(Type configurationClassType, IConfigurationClassInterceptor interceptor)
|
||||
{
|
||||
if (configurationClassType.IsSealed)
|
||||
{
|
||||
throw new ArgumentException(String.Format(
|
||||
"[Configuration] classes '{0}' cannot be sealed [{0}].", configurationClassType.FullName));
|
||||
}
|
||||
|
||||
this.Name = "ConfigurationClassProxy";
|
||||
this.DeclaredMembersOnly = false;
|
||||
this.BaseType = configurationClassType;
|
||||
this.TargetType = configurationClassType;
|
||||
|
||||
this.interceptor = interceptor;
|
||||
}
|
||||
|
||||
public override Type BuildProxyType()
|
||||
{
|
||||
IDictionary targetMethods = new Hashtable();
|
||||
|
||||
TypeBuilder typeBuilder = CreateTypeBuilder(Name, BaseType);
|
||||
|
||||
// apply custom attributes to the proxy type.
|
||||
//ApplyTypeAttributes(typeBuilder, BaseType);
|
||||
|
||||
// declare interceptor field
|
||||
interceptorField = typeBuilder.DefineField("__Interceptor", typeof(IConfigurationClassInterceptor),
|
||||
FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly);
|
||||
|
||||
// create constructors
|
||||
ImplementConstructors(typeBuilder);
|
||||
|
||||
// proxy base virtual methods
|
||||
InheritType(typeBuilder,
|
||||
new ConfigurationClassProxyMethodBuilder(typeBuilder, this, false, targetMethods),
|
||||
BaseType, this.DeclaredMembersOnly);
|
||||
|
||||
Type proxyType = typeBuilder.CreateType();
|
||||
|
||||
// set target method references
|
||||
foreach (DictionaryEntry entry in targetMethods)
|
||||
{
|
||||
FieldInfo targetMethodFieldInfo = proxyType.GetField((string)entry.Key, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
targetMethodFieldInfo.SetValue(proxyType, entry.Value);
|
||||
}
|
||||
|
||||
// set interceptor
|
||||
FieldInfo interceptorFieldInfo = proxyType.GetField("__Interceptor", BindingFlags.NonPublic | BindingFlags.Static);
|
||||
interceptorFieldInfo.SetValue(proxyType, this.interceptor);
|
||||
|
||||
return proxyType;
|
||||
}
|
||||
|
||||
public void PushInterceptor(ILGenerator il)
|
||||
{
|
||||
il.Emit(OpCodes.Ldarg_0);
|
||||
il.Emit(OpCodes.Ldfld, interceptorField);
|
||||
}
|
||||
}
|
||||
|
||||
private sealed class ConfigurationClassProxyMethodBuilder : AbstractProxyMethodBuilder
|
||||
{
|
||||
public static readonly MethodInfo ProcessDefinitionMethod =
|
||||
typeof(IConfigurationClassInterceptor).GetMethod("ProcessDefinition", BindingFlags.Instance | BindingFlags.Public);
|
||||
|
||||
private ConfigurationClassProxyTypeBuilder customProxyGenerator;
|
||||
|
||||
private IDictionary targetMethods;
|
||||
|
||||
public ConfigurationClassProxyMethodBuilder(
|
||||
TypeBuilder typeBuilder, ConfigurationClassProxyTypeBuilder proxyGenerator,
|
||||
bool explicitImplementation, IDictionary targetMethods)
|
||||
: base(typeBuilder, proxyGenerator, explicitImplementation)
|
||||
{
|
||||
this.customProxyGenerator = proxyGenerator;
|
||||
this.targetMethods = targetMethods;
|
||||
}
|
||||
|
||||
protected override void GenerateMethod(
|
||||
ILGenerator il, MethodInfo method, MethodInfo interfaceMethod)
|
||||
{
|
||||
// Declare local variables
|
||||
LocalBuilder interceptedReturnValue = il.DeclareLocal(typeof(Object));
|
||||
//#if DEBUG
|
||||
// interceptedReturnValue.SetLocalSymInfo("interceptedReturnValue");
|
||||
//#endif
|
||||
LocalBuilder returnValue = null;
|
||||
if (method.ReturnType != typeof(void))
|
||||
{
|
||||
returnValue = il.DeclareLocal(method.ReturnType);
|
||||
//#if DEBUG
|
||||
// returnValue.SetLocalSymInfo("returnValue");
|
||||
//#endif
|
||||
}
|
||||
|
||||
// Declare static field that will cache base method
|
||||
string methodId = "_m" + Guid.NewGuid().ToString("N");
|
||||
targetMethods.Add(methodId, method);
|
||||
FieldBuilder targetMethodCacheField = typeBuilder.DefineField(methodId, typeof(MethodInfo),
|
||||
FieldAttributes.Private | FieldAttributes.Static | FieldAttributes.InitOnly);
|
||||
|
||||
// Call IConfigurationClassInterceptor.TryGetObject method
|
||||
il.Emit(OpCodes.Ldnull);
|
||||
il.Emit(OpCodes.Stloc, interceptedReturnValue);
|
||||
customProxyGenerator.PushInterceptor(il);
|
||||
il.Emit(OpCodes.Ldsfld, targetMethodCacheField);
|
||||
il.Emit(OpCodes.Ldloca_S, interceptedReturnValue);
|
||||
il.EmitCall(OpCodes.Callvirt, ProcessDefinitionMethod, null);
|
||||
Label jmpBaseCall = il.DefineLabel();
|
||||
Label jmpEndIf = il.DefineLabel();
|
||||
il.Emit(OpCodes.Brfalse_S, jmpBaseCall);
|
||||
|
||||
// if true
|
||||
if (returnValue != null)
|
||||
{
|
||||
il.Emit(OpCodes.Ldloc, interceptedReturnValue);
|
||||
if (method.ReturnType.IsValueType || method.ReturnType.IsGenericParameter)
|
||||
{
|
||||
il.Emit(OpCodes.Unbox_Any, method.ReturnType);
|
||||
}
|
||||
il.Emit(OpCodes.Stloc, returnValue);
|
||||
il.Emit(OpCodes.Br, jmpEndIf);
|
||||
}
|
||||
|
||||
// if false
|
||||
il.MarkLabel(jmpBaseCall);
|
||||
CallDirectBaseMethod(il, method);
|
||||
if (returnValue != null)
|
||||
{
|
||||
il.Emit(OpCodes.Stloc, returnValue);
|
||||
}
|
||||
|
||||
// end if
|
||||
il.MarkLabel(jmpEndIf);
|
||||
|
||||
// return value
|
||||
if (returnValue != null)
|
||||
{
|
||||
il.Emit(OpCodes.Ldloc, returnValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,145 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Objects.Factory.Parsing;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a <see cref="ConfigurationAttribute"/> class method marked with the <see cref="ObjectDefAttribute"/>.
|
||||
/// </summary>
|
||||
public class ConfigurationClassMethod
|
||||
{
|
||||
private readonly ConfigurationClass _configurationClass;
|
||||
|
||||
private readonly 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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configuration class.
|
||||
/// </summary>
|
||||
/// <value>The configuration class.</value>
|
||||
public ConfigurationClass ConfigurationClass
|
||||
{
|
||||
get { return _configurationClass; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the method metadata.
|
||||
/// </summary>
|
||||
/// <value>The method metadata.</value>
|
||||
public MethodInfo MethodMetadata
|
||||
{
|
||||
get { return _methodInfo; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the resource location.
|
||||
/// </summary>
|
||||
/// <value>The resource location.</value>
|
||||
public Location ResourceLocation
|
||||
{
|
||||
get { return new Location(_configurationClass.Resource, _methodInfo); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a <see cref="System.String"/> that represents this instance.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A <see cref="System.String"/> that represents this instance.
|
||||
/// </returns>
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}:name={1},declaringClass={2}", GetType().Name, _methodInfo.Name,
|
||||
_methodInfo.DeclaringType.FullName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the specified problem reporter.
|
||||
/// </summary>
|
||||
/// <param name="problemReporter">The problem reporter.</param>
|
||||
public void Validate(IProblemReporter problemReporter)
|
||||
{
|
||||
//TODO: investigate whether this should be "if method has ObjectDef attribute" instead of "if class has Configuration attribute"
|
||||
if (
|
||||
Attribute.GetCustomAttribute(ConfigurationClass.ConfigurationClassType, typeof (ConfigurationAttribute)) !=
|
||||
null)
|
||||
{
|
||||
|
||||
if (MethodMetadata.IsStatic)
|
||||
{
|
||||
problemReporter.Error(new StaticMethodError(MethodMetadata.Name, ResourceLocation));
|
||||
}
|
||||
|
||||
if (!MethodMetadata.IsVirtual)
|
||||
{
|
||||
problemReporter.Error(new NonVirtualMethodError(MethodMetadata.Name, ResourceLocation));
|
||||
}
|
||||
|
||||
if (MethodMetadata.GetParameters().Length != 0)
|
||||
{
|
||||
problemReporter.Error(new MethodWithParametersError(MethodMetadata.Name, ResourceLocation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class MethodWithParametersError : Problem
|
||||
{
|
||||
public MethodWithParametersError(string methodName, Location location)
|
||||
: base(
|
||||
String.Format(
|
||||
"Method '{0}' must not accept parameters; remove the method's parameters 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)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,308 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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
|
||||
|
||||
#region
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
using Common.Logging;
|
||||
|
||||
using Spring.Core.TypeResolution;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Stereotype;
|
||||
|
||||
#endregion
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Reads the class with the <see cref="ConfigurationAttribute"/> applied and converts it into an <see cref="Spring.Objects.Factory.Config.IObjectDefinition"/> instance.
|
||||
/// </summary>
|
||||
public class ConfigurationClassObjectDefinitionReader
|
||||
{
|
||||
private static readonly ILog Logger = LogManager.GetLogger<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;
|
||||
}
|
||||
|
||||
private static bool HasAttributeOnMethods(Type objectType, Type attributeType)
|
||||
{
|
||||
Collections.Generic.ISet<MethodInfo> methods = ConfigurationClassParser.GetAllMethodsWithCustomAttributeForClass(objectType,
|
||||
attributeType);
|
||||
foreach (MethodInfo method in methods)
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(method, attributeType) != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the object definitions.
|
||||
/// </summary>
|
||||
/// <param name="configurationModel">The configuration model.</param>
|
||||
public void LoadObjectDefinitions(Collections.Generic.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.ObjectTypeName = className;
|
||||
configObjectDef.ObjectType = configClass.ConfigurationClassType;
|
||||
if (CheckConfigurationClassCandidate(configClass.ConfigurationClassType))
|
||||
{
|
||||
String configObjectName = ObjectDefinitionReaderUtils.RegisterWithGeneratedName(configObjectDef,
|
||||
_registry);
|
||||
configClass.ObjectName = configObjectName;
|
||||
Logger.Debug(m => m("Registered object definition for imported [Configuration] class {0}",
|
||||
configObjectName));
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks the class to see if it is a candidate to be a <see cref="ConfigurationAttribute"/> source.
|
||||
/// </summary>
|
||||
/// <param name="objectDefinition">The object definition.</param>
|
||||
/// <returns></returns>
|
||||
public static bool CheckConfigurationClassCandidate(IObjectDefinition objectDefinition)
|
||||
{
|
||||
Type objectType = null;
|
||||
if (objectDefinition is AbstractObjectDefinition)
|
||||
{
|
||||
AbstractObjectDefinition definition = (AbstractObjectDefinition)objectDefinition;
|
||||
if (definition.HasObjectType)
|
||||
{
|
||||
objectType = definition.ObjectType;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (definition.ObjectTypeName != null && !definition.IsAbstract)
|
||||
{
|
||||
objectType = TypeResolutionUtils.ResolveType(definition.ObjectTypeName);
|
||||
}
|
||||
}
|
||||
if (objectType != null)
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(objectType, typeof(ConfigurationAttribute)) != null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (Attribute.GetCustomAttribute(objectType, typeof(ComponentAttribute)) != null ||
|
||||
HasAttributeOnMethods(objectType, typeof(ObjectDefAttribute)))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private bool CheckConfigurationClassCandidate(Type type)
|
||||
{
|
||||
if (type != null)
|
||||
{
|
||||
return (Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute)) != null);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
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();
|
||||
|
||||
objDef.FactoryObjectName = configClass.ObjectName;
|
||||
objDef.FactoryMethodName = metadata.Name;
|
||||
objDef.AutowireMode = Objects.Factory.Config.AutoWiringMode.Constructor;
|
||||
|
||||
// consider name and any aliases
|
||||
//Dictionary<String, Object> ObjectAttributes = metadata.getAnnotationAttributes(Object.class.getName());
|
||||
object[] objectAttributes = metadata.GetCustomAttributes(typeof(ObjectDefAttribute), true);
|
||||
List<string> names = new List<string>();
|
||||
foreach (object t in objectAttributes)
|
||||
{
|
||||
string[] namesAndAliases = ((ObjectDefAttribute)t).NamesToArray;
|
||||
|
||||
if (namesAndAliases != null)
|
||||
{
|
||||
names.Add(metadata.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
namesAndAliases = new[] { metadata.Name };
|
||||
}
|
||||
|
||||
names.AddRange(namesAndAliases);
|
||||
}
|
||||
|
||||
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
|
||||
Logger.Debug(m => m("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;
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: container does not presently support the concept of Primary object defintion for type resolution
|
||||
//if (Attribute.GetCustomAttribute(metadata, typeof(PrimaryAttribute)) != null)
|
||||
//{
|
||||
// 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;
|
||||
}
|
||||
|
||||
//TODO: container does not presently support autowiring to the degree needed to support this feature as of yet
|
||||
//Autowire autowire = (Autowire) ObjectAttributes.get("autowire");
|
||||
//if (autowire.isAutowire()) {
|
||||
// ObjectDef.setAutowireMode(autowire.value());
|
||||
//}
|
||||
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(ObjectDefAttribute)) != null)
|
||||
{
|
||||
objDef.InitMethodName =
|
||||
(Attribute.GetCustomAttribute(metadata, typeof(ObjectDefAttribute)) as ObjectDefAttribute).
|
||||
InitMethod;
|
||||
objDef.DestroyMethodName =
|
||||
(Attribute.GetCustomAttribute(metadata, typeof(ObjectDefAttribute)) as ObjectDefAttribute).
|
||||
DestroyMethod;
|
||||
}
|
||||
|
||||
// consider scoping
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(ScopeAttribute)) != null)
|
||||
{
|
||||
objDef.Scope =
|
||||
(Attribute.GetCustomAttribute(metadata, typeof(ScopeAttribute)) as ScopeAttribute).ObjectScope.ToString();
|
||||
}
|
||||
|
||||
Logger.Debug(m => m("Registering Object definition for [ObjectDef] method {0}.{1}()",
|
||||
configClass.ConfigurationClassType.Name, objectName));
|
||||
|
||||
_registry.RegisterObjectDefinition(objectName, objDef);
|
||||
}
|
||||
|
||||
private void LoadObjectDefinitionsFromImportedResources(IEnumerable<KeyValuePair<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
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,194 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Collections.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Parses classes with the <see cref="ConfigurationAttribute"/> applied to them.
|
||||
/// </summary>
|
||||
public class ConfigurationClassParser
|
||||
{
|
||||
private Collections.Generic.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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the configuration classes.
|
||||
/// </summary>
|
||||
/// <value>The configuration classes.</value>
|
||||
public Collections.Generic.ISet<ConfigurationClass> ConfigurationClasses
|
||||
{
|
||||
get { return _configurationClasses; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parses the specified type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <param name="objectName">Name of the object.</param>
|
||||
public void Parse(Type type, string objectName)
|
||||
{
|
||||
ProcessConfigurationClass(new ConfigurationClass(objectName, type));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates this instance.
|
||||
/// </summary>
|
||||
public void Validate()
|
||||
{
|
||||
foreach (ConfigurationClass configClass in ConfigurationClasses)
|
||||
{
|
||||
configClass.Validate(_problemReporter);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Processes the configuration class.
|
||||
/// </summary>
|
||||
/// <param name="configurationClass">The configuration class.</param>
|
||||
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)
|
||||
{
|
||||
|
||||
Attribute[] importAttributes = Attribute.GetCustomAttributes(configurationClass.ConfigurationClassType, typeof(ImportAttribute));
|
||||
|
||||
if (importAttributes.Length > 0)
|
||||
{
|
||||
foreach (Attribute importAttribute in importAttributes)
|
||||
{
|
||||
ImportAttribute attrib = importAttribute as ImportAttribute;
|
||||
|
||||
if (null != attrib)
|
||||
{
|
||||
ProcessImport(configurationClass, attrib.Types);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Attribute[] importResourceAttributes = Attribute.GetCustomAttributes(configurationClass.ConfigurationClassType, typeof(ImportResourceAttribute));
|
||||
|
||||
if (importResourceAttributes.Length > 0)
|
||||
{
|
||||
foreach (Attribute importResourceAttribute in importResourceAttributes)
|
||||
{
|
||||
ImportResourceAttribute attrib = importResourceAttribute as ImportResourceAttribute;
|
||||
|
||||
if (null != attrib)
|
||||
{
|
||||
foreach (string resource in attrib.Resources)
|
||||
{
|
||||
configurationClass.AddImportedResource(resource, attrib.DefinitionReader);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Collections.Generic.ISet<MethodInfo> definitionMethods = GetAllMethodsWithCustomAttributeForClass(configurationClass.ConfigurationClassType, typeof(ObjectDefAttribute));
|
||||
foreach (MethodInfo definitionMethod in definitionMethods)
|
||||
{
|
||||
configurationClass.Methods.Add(new ConfigurationClassMethod(definitionMethod, configurationClass));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets all methods with custom attribute for class.
|
||||
/// </summary>
|
||||
/// <param name="theClass">The class.</param>
|
||||
/// <param name="customAttribute">The custom attribute.</param>
|
||||
/// <returns></returns>
|
||||
public static Collections.Generic.ISet<MethodInfo> GetAllMethodsWithCustomAttributeForClass(Type theClass, Type customAttribute)
|
||||
{
|
||||
Collections.Generic.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, IEnumerable<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)
|
||||
)
|
||||
{ }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,192 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
|
||||
using Common.Logging;
|
||||
|
||||
using Spring.Core;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Collections.Generic;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Postprocesses the <see cref="ConfigurationAttribute"/> applied types registered with the <see cref="IApplicationContext"/>.
|
||||
/// </summary>
|
||||
public class ConfigurationClassPostProcessor : IObjectDefinitionRegistryPostProcessor, IOrdered
|
||||
{
|
||||
#region Logging
|
||||
|
||||
private static readonly ILog Logger = LogManager.GetLogger<ConfigurationClassPostProcessor>();
|
||||
|
||||
#endregion
|
||||
|
||||
private bool _postProcessObjectDefinitionRegistryCalled;
|
||||
|
||||
private bool _postProcessObjectFactoryCalled;
|
||||
|
||||
private IProblemReporter _problemReporter = new FailFastProblemReporter();
|
||||
|
||||
/// <summary>
|
||||
/// Return the order value of this object, where a higher value means greater in
|
||||
/// terms of sorting.
|
||||
/// </summary>
|
||||
/// <value></value>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// Normally starting with 0 or 1, with <see cref="F:System.Int32.MaxValue"/> indicating
|
||||
/// greatest. Same order values will result in arbitrary positions for the affected
|
||||
/// objects.
|
||||
/// </p>
|
||||
/// <p>
|
||||
/// Higher value can be interpreted as lower priority, consequently the first object
|
||||
/// has highest priority.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
/// <returns>The order value.</returns>
|
||||
public int Order
|
||||
{
|
||||
get { return int.MinValue; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the problem reporter.
|
||||
/// </summary>
|
||||
/// <value>The problem reporter.</value>
|
||||
public IProblemReporter ProblemReporter
|
||||
{
|
||||
set { _problemReporter = (value ?? new FailFastProblemReporter()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Postsprocesses the object definition registry.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry.</param>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Postprocesses the object factory.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory">The object factory.</param>
|
||||
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)
|
||||
{
|
||||
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(objectFactory);
|
||||
|
||||
IList<string> objectNames = objectFactory.GetObjectDefinitionNames();
|
||||
|
||||
foreach (string name in objectNames)
|
||||
{
|
||||
IObjectDefinition objDef = objectFactory.GetObjectDefinition(name);
|
||||
|
||||
if (((AbstractObjectDefinition)objDef).HasObjectType)
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(objDef.ObjectType, typeof(ConfigurationAttribute)) != null)
|
||||
{
|
||||
//TODO check type of object isn't infrastructure type.
|
||||
|
||||
Type configClass = objDef.ObjectType;
|
||||
Type enhancedClass = enhancer.Enhance(configClass);
|
||||
|
||||
Logger.Debug(m => m("Replacing object definition '{0}' existing class '{1}' with enhanced class", name, configClass.FullName));
|
||||
|
||||
((IConfigurableObjectDefinition)objDef).ObjectType = enhancedClass;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessConfigObjectDefinitions(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
Collections.Generic.ISet<ObjectDefinitionHolder> configCandidates = new HashedSet<ObjectDefinitionHolder>();
|
||||
foreach (string objectName in registry.GetObjectDefinitionNames())
|
||||
{
|
||||
IObjectDefinition objectDef = registry.GetObjectDefinition(objectName);
|
||||
if (ConfigurationClassObjectDefinitionReader.CheckConfigurationClassCandidate(objectDef))
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
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="DependsOnAttribute"/> at the class level has no effect unless component-scanning
|
||||
/// is being used. If a <see cref="DependsOnAttribute"/>-attributed class is declared via XML,
|
||||
/// <see cref="DependsOnAttribute"/> attribute metadata is ignored, and
|
||||
/// <object depends-on="..."/> 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(params string[] name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string[] Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Scanner that can filter types from assemblies based on constraints.
|
||||
/// </summary>
|
||||
public interface IAssemblyTypeScanner
|
||||
{
|
||||
/// <summary>
|
||||
/// Add the Assembly containing the specified <see cref="Type"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner AssemblyHavingType<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Adds the predicate to the assembly filter constraints.
|
||||
/// </summary>
|
||||
/// <param name="assemblyPredicate">The assembly predicate.</param>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the predicte to the include filter for <see cref="Type"/>.
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate.</param>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// Adds the predicte to the exclude filter for <see cref="Type"/>.
|
||||
/// </summary>
|
||||
/// <param name="predicate">The predicate.</param>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate);
|
||||
|
||||
/// <summary>
|
||||
/// Includes the specific types.
|
||||
/// </summary>
|
||||
/// <param name="typeSource">The types.</param>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Includes the type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The <see cref="Type"/> to include.</typeparam>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner IncludeType<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Excludes the type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The <see cref="Type"/> to exclude.</typeparam>
|
||||
/// <returns></returns>
|
||||
IAssemblyTypeScanner ExcludeType<T>();
|
||||
|
||||
/// <summary>
|
||||
/// Perform the Scan, applying all provided
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
IEnumerable<Type> Scan();
|
||||
}
|
||||
}
|
||||
64
src/Spring/Spring.Core/Context/Attributes/ImportAttribute.cs
Normal file
64
src/Spring/Spring.Core/Context/Attributes/ImportAttribute.cs
Normal file
@@ -0,0 +1,64 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates one or more <see cref="ConfigurationAttribute"/> classes to import.
|
||||
///
|
||||
/// <para>Provides functionality equivalent to the <import/> element in Spring XML.
|
||||
/// Only supported for actual <see cref="ConfigurationAttribute"/>-attributed classes.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>If XML or other non-<see cref="ConfigurationAttribute"/> object definition resources need to be
|
||||
/// imported, use <see cref="ImportResourceAttribute"/>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
public class ImportAttribute : Attribute
|
||||
{
|
||||
private Type[] _types;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Import class.
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
public ImportAttribute(params Type[] types)
|
||||
{
|
||||
_types = types;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="ConfigurationAttribute"/> class or classes to import.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public Type[] Types
|
||||
{
|
||||
get { return _types; }
|
||||
set
|
||||
{
|
||||
_types = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Core.IO;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Supports providing one or more <see cref="IResource"/> implementations to import when creating <see cref="RootObjectDefinition"/>s.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
79
src/Spring/Spring.Core/Context/Attributes/LazyAttribute.cs
Normal file
79
src/Spring/Spring.Core/Context/Attributes/LazyAttribute.cs
Normal file
@@ -0,0 +1,79 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether a object is to be lazily initialized.
|
||||
///
|
||||
/// <para>If this attribute 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="ConfigurationAttribute"/> class, this indicates that all
|
||||
/// <see cref="ObjectDefAttribute"/> methods within that <see cref="ConfigurationAttribute"/> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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.Generic;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Limited extension methods reproducing the small subset of LINQ that is needed in the code; required b/c the project targets .NET 2.0 where LINQ is not available.
|
||||
/// </summary>
|
||||
internal static class LinqExtensionMethods
|
||||
{
|
||||
public static int Count<TSource>(this IEnumerable<TSource> source)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
|
||||
int counter = 0;
|
||||
foreach (TSource obj in source)
|
||||
{
|
||||
counter++;
|
||||
}
|
||||
|
||||
return counter;
|
||||
}
|
||||
|
||||
internal static bool Contains<TSource>(this IEnumerable<TSource> source, TSource value) where TSource : class
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
|
||||
foreach (TSource obj in source)
|
||||
{
|
||||
if (obj == value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
internal static IEnumerable<TSource> AsEnumerable<TSource>(this IEnumerable<TSource> source)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
|
||||
IList<TSource> results = new List<TSource>();
|
||||
|
||||
foreach (TSource obj in source)
|
||||
{
|
||||
results.Add(obj);
|
||||
}
|
||||
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
internal static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source,
|
||||
Predicate<TSource> predicate)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
if (predicate == null) throw new ArgumentNullException("predicate");
|
||||
|
||||
IList<TSource> matching = new List<TSource>();
|
||||
|
||||
foreach (TSource obj in source)
|
||||
{
|
||||
if (predicate(obj))
|
||||
{
|
||||
matching.Add(obj);
|
||||
}
|
||||
}
|
||||
|
||||
return matching;
|
||||
}
|
||||
|
||||
|
||||
internal static bool Any<TSource>(this IEnumerable<TSource> source, Predicate<TSource> predicate)
|
||||
{
|
||||
if (source == null) throw new ArgumentNullException("source");
|
||||
if (predicate == null) throw new ArgumentNullException("predicate");
|
||||
|
||||
foreach (TSource obj in source)
|
||||
{
|
||||
if (predicate(obj))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
122
src/Spring/Spring.Core/Context/Attributes/ObjectDefAttribute.cs
Normal file
122
src/Spring/Spring.Core/Context/Attributes/ObjectDefAttribute.cs
Normal file
@@ -0,0 +1,122 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Identifies the Method as providing and Object Definition.
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class ObjectDefAttribute : Attribute
|
||||
{
|
||||
//private AutoWiringMode _autoWire = AutoWiringMode.No;
|
||||
|
||||
private string _destroyMethod;
|
||||
|
||||
private string _initMethod;
|
||||
|
||||
private string _names;
|
||||
|
||||
//TODO: constructor injection via factory methods is not presently supported by the container
|
||||
///// <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 multiple, 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;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the comma-delimited list of names/aliases as an array.
|
||||
/// </summary>
|
||||
/// <value>The array of names.</value>
|
||||
public string[] NamesToArray
|
||||
{
|
||||
get
|
||||
{
|
||||
return StringUtils.DelimitedListToStringArray(_names, ",");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
107
src/Spring/Spring.Core/Context/Attributes/ReflectionOnlyUtils.cs
Normal file
107
src/Spring/Spring.Core/Context/Attributes/ReflectionOnlyUtils.cs
Normal file
@@ -0,0 +1,107 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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.Generic;
|
||||
using System.Reflection;
|
||||
using System.Security.Permissions;
|
||||
using System.Security.Policy;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Utilities to provide support for manipulating ReflectionOnly types in the <see cref="AppDomain"/>.
|
||||
/// </summary>
|
||||
public static class ReflectionOnlyUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Load the <see cref="Assembly"/> into the ReflectionsOnly context based on its partial name.
|
||||
/// </summary>
|
||||
/// <param name="partialName">The partial name.</param>
|
||||
/// <returns>The matching <see cref="Assembly"/></returns>
|
||||
public static Assembly ReflectionOnlyLoadWithPartialName(string partialName)
|
||||
{
|
||||
return ReflectionOnlyLoadWithPartialName(partialName, null);
|
||||
}
|
||||
|
||||
private static Assembly ReflectionOnlyLoadWithPartialName(string partialName, Evidence securityEvidence)
|
||||
{
|
||||
if (securityEvidence != null)
|
||||
new SecurityPermission(SecurityPermissionFlag.ControlEvidence).Demand();
|
||||
|
||||
AssemblyName fileName = new AssemblyName(partialName);
|
||||
|
||||
var assembly = nLoad(fileName, null, securityEvidence, null, null, false, true);
|
||||
|
||||
if (assembly != null)
|
||||
return assembly;
|
||||
|
||||
var assemblyRef = EnumerateCache(fileName);
|
||||
|
||||
if (assemblyRef != null)
|
||||
return InternalLoad(assemblyRef, securityEvidence, null, true);
|
||||
|
||||
return assembly;
|
||||
}
|
||||
|
||||
private static Assembly nLoad(params object[] args)
|
||||
{
|
||||
return (Assembly)typeof(Assembly)
|
||||
.GetMethod("nLoad", BindingFlags.NonPublic | BindingFlags.Static)
|
||||
.Invoke(null, args);
|
||||
}
|
||||
|
||||
private static AssemblyName EnumerateCache(params object[] args)
|
||||
{
|
||||
return (AssemblyName)typeof(Assembly)
|
||||
.GetMethod("EnumerateCache", BindingFlags.NonPublic | BindingFlags.Static)
|
||||
.Invoke(null, args);
|
||||
}
|
||||
|
||||
private static Assembly InternalLoad(params object[] args)
|
||||
{
|
||||
// Easiest to query because the StackCrawlMark type is internal
|
||||
/*
|
||||
* TODO: cannot do it this way under .NET 2.0 b/c .First(...) relies on LINQ which we don't have (yet)
|
||||
* (plan to eventually uncomment this impl once we move to .NET 3.5 or greater)
|
||||
*
|
||||
return (Assembly)
|
||||
typeof(Assembly).GetMethods(BindingFlags.NonPublic | BindingFlags.Static)
|
||||
.First(m => m.Name == "InternalLoad" &&
|
||||
m.GetParameters()[0].ParameterType == typeof (AssemblyName))
|
||||
.Invoke(null, args);
|
||||
*/
|
||||
IEnumerable<MethodInfo> methods =
|
||||
typeof(Assembly).GetMethods(BindingFlags.NonPublic | BindingFlags.Static).Where(
|
||||
delegate(MethodInfo m)
|
||||
{
|
||||
return m.Name == "InternalLoad" &&
|
||||
m.GetParameters()[0].ParameterType == typeof(AssemblyName);
|
||||
});
|
||||
|
||||
foreach (MethodInfo methodInfo in methods)
|
||||
{
|
||||
return (Assembly)methodInfo.Invoke(null, args);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// AssemblyTypeScanner that provides for applying a final hard-coded Required Constraint to all types found in the the scanned assemblies
|
||||
/// in addition to respecting the constraints passed to it during its configuration.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
public abstract class RequiredConstraintAssemblyTypeScanner : AssemblyTypeScanner
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the compound predicate is satisfied by the specified type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the compound predicate is satisfied by the specified type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected override bool IsCompoundPredicateSatisfiedBy(Type type)
|
||||
{
|
||||
return IsRequiredConstraintSatisfiedBy(type) && IsIncludedType(type) && !IsExcludedType(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the required constraint is satisfied by the specified type.
|
||||
/// </summary>
|
||||
/// <param name="type">The type.</param>
|
||||
/// <returns>
|
||||
/// <c>true</c> if the required constraint is satisfied by the specified type; otherwise, <c>false</c>.
|
||||
/// </returns>
|
||||
protected abstract bool IsRequiredConstraintSatisfiedBy(Type type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,134 @@
|
||||
#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;
|
||||
using Spring.Objects;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Stereotype;
|
||||
using Spring.Objects.Factory.Attributes;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// A GenericObjectDefinition that provides attribute driven propulation
|
||||
/// of properties like LazyInit, Scope or Qualifier
|
||||
/// </summary>
|
||||
public class ScannedGenericObjectDefinition : GenericObjectDefinition
|
||||
{
|
||||
/// <summary>
|
||||
/// Name provided by the Component Attribute
|
||||
/// </summary>
|
||||
private string _componentName;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a GenericObjectDefinition that applies the default values provided
|
||||
/// in the XML Spring config document. Additionally parses the specific class
|
||||
/// attributesthat allows the definition of LazyInit, Scope or Qualifier
|
||||
/// </summary>
|
||||
/// <param name="typeOfObject">Type of scanned component</param>
|
||||
/// <param name="defaults">Defualts provided in Spring Config document</param>
|
||||
public ScannedGenericObjectDefinition(Type typeOfObject, DocumentDefaultsDefinition defaults)
|
||||
{
|
||||
ObjectType = typeOfObject;
|
||||
|
||||
ParseName();
|
||||
ApplyDefaults(defaults);
|
||||
ParseScopeAttribute();
|
||||
ParseLazyAttribute();
|
||||
ParseQualifierAttribute();
|
||||
}
|
||||
|
||||
private void ParseName()
|
||||
{
|
||||
var attr = Attribute.GetCustomAttribute(ObjectType, typeof (ComponentAttribute), true) as ComponentAttribute;
|
||||
if (attr != null && !string.IsNullOrEmpty(attr.Name))
|
||||
_componentName = attr.Name;
|
||||
}
|
||||
|
||||
private void ApplyDefaults(DocumentDefaultsDefinition defaults)
|
||||
{
|
||||
if (defaults == null)
|
||||
return;
|
||||
|
||||
bool lazyInit = false;
|
||||
bool.TryParse(defaults.LazyInit, out lazyInit);
|
||||
IsLazyInit = lazyInit;
|
||||
}
|
||||
|
||||
private void ParseScopeAttribute()
|
||||
{
|
||||
var attr = Attribute.GetCustomAttribute(ObjectType, typeof(ScopeAttribute), true) as ScopeAttribute;
|
||||
if (attr != null)
|
||||
Scope = attr.ObjectScope.ToString().ToLower();
|
||||
}
|
||||
|
||||
private void ParseLazyAttribute()
|
||||
{
|
||||
var attr = Attribute.GetCustomAttribute(ObjectType, typeof(LazyAttribute), true) as LazyAttribute;
|
||||
if (attr != null)
|
||||
IsLazyInit = attr.LazyInitialize;
|
||||
}
|
||||
|
||||
private void ParseQualifierAttribute()
|
||||
{
|
||||
var attr = Attribute.GetCustomAttribute(ObjectType, typeof(QualifierAttribute), true) as QualifierAttribute;
|
||||
if (attr != null)
|
||||
{
|
||||
var qualifier = new AutowireCandidateQualifier(attr.GetType());
|
||||
|
||||
if (!string.IsNullOrEmpty(attr.Value))
|
||||
qualifier.SetAttribute(AutowireCandidateQualifier.VALUE_KEY, attr.Value);
|
||||
|
||||
ParseQualifierProperties(attr, qualifier);
|
||||
|
||||
AddQualifier(qualifier);
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseQualifierProperties(QualifierAttribute attr, AutowireCandidateQualifier qualifier)
|
||||
{
|
||||
foreach (var property in attr.GetType().GetProperties())
|
||||
{
|
||||
if (!property.Name.Equals("TypeId") && !property.Name.Equals("Value"))
|
||||
{
|
||||
object value = property.GetValue(attr, null);
|
||||
if (value != null)
|
||||
{
|
||||
var attribute = new ObjectMetadataAttribute(property.Name, value);
|
||||
qualifier.AddMetadataAttribute(attribute);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides the name of the object scanned
|
||||
/// </summary>
|
||||
/// <returns>return the provided attribute name of the full object type name</returns>
|
||||
public string ComponentName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _componentName;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
66
src/Spring/Spring.Core/Context/Attributes/ScopeAttribute.cs
Normal file
66
src/Spring/Spring.Core/Context/Attributes/ScopeAttribute.cs
Normal file
@@ -0,0 +1,66 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 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="ObjectDefAttribute"/> 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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Core.TypeResolution;
|
||||
using Common.Logging;
|
||||
|
||||
namespace Spring.Context.Attributes.TypeFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Abstract Type Filter that provides methods to load a required type from assembly.
|
||||
/// </summary>
|
||||
public abstract class AbstractLoadTypeFilter : ITypeFilter
|
||||
{
|
||||
private static readonly ILog Logger = LogManager.GetLogger<AbstractLoadTypeFilter>();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Required Type to compare against provided Type
|
||||
/// </summary>
|
||||
protected Type RequiredType;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Determine a match based on the given type object.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns>true if there is a match; false is there is no match</returns>
|
||||
public abstract bool Match(Type type);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Is loading a Type from a string passed to method in the form [Type.FullName], [Assembly.Name]
|
||||
/// </summary>
|
||||
protected void GetRequiredType(string typeToLoad)
|
||||
{
|
||||
try
|
||||
{
|
||||
RequiredType = TypeResolutionUtils.ResolveType(typeToLoad);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
RequiredType = null;
|
||||
Logger.Error("Can't load type defined in exoression:" + typeToLoad);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
namespace Spring.Context.Attributes.TypeFilters
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A simple filter which matches classes that are assignable to a given type.
|
||||
/// </summary>
|
||||
public class AssignableTypeFilter : AbstractLoadTypeFilter
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Create a Type Filter with required type
|
||||
/// </summary>
|
||||
/// <param name="expression">type name including assembly name</param>
|
||||
public AssignableTypeFilter(string expression)
|
||||
{
|
||||
GetRequiredType(expression);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine a match based on the given type object.
|
||||
/// </summary>
|
||||
/// <param name="type">Type to compare against</param>
|
||||
/// <returns>true if there is a match; false is there is no match</returns>
|
||||
public override bool Match(Type type)
|
||||
{
|
||||
if (RequiredType == null)
|
||||
return false;
|
||||
|
||||
return (type.GetInterfaces().Any(i => i.Equals(RequiredType)) || RequiredType.Equals(type.BaseType));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
namespace Spring.Context.Attributes.TypeFilters
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// A simple filter which matches classes with a given attribute,
|
||||
/// checking inherited annotations as well.
|
||||
/// </summary>
|
||||
public class AttributeTypeFilter : AbstractLoadTypeFilter
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Creates a Type Filter with required type attribute
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
public AttributeTypeFilter(string expression)
|
||||
{
|
||||
GetRequiredType(expression);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine a match based on the given type object.
|
||||
/// </summary>
|
||||
/// <param name="type">Type to compare against</param>
|
||||
/// <returns>true if there is a match; false is there is no match</returns>
|
||||
public override bool Match(Type type)
|
||||
{
|
||||
if (RequiredType == null)
|
||||
return false;
|
||||
|
||||
return (Attribute.GetCustomAttribute(type, RequiredType) != null);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,91 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Common.Logging;
|
||||
using Spring.Core.TypeResolution;
|
||||
using Spring.Util;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes.TypeFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a new instance of a givin type string
|
||||
/// </summary>
|
||||
public static class CustomTypeFactory
|
||||
{
|
||||
private static readonly ILog Logger = LogManager.GetLogger(typeof(CustomTypeFactory).FullName);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of given type filter type string
|
||||
/// </summary>
|
||||
/// <param name="expression">Custom type filter to create</param>
|
||||
/// <returns>An instance of ITypeFilter or NULL if no instance can be created</returns>
|
||||
public static ITypeFilter GetTypeFilter(string expression)
|
||||
{
|
||||
return GetCustomType(expression) as ITypeFilter;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of given name generator type string
|
||||
/// </summary>
|
||||
/// <param name="expression">Custom type name generator string to create</param>
|
||||
/// <returns>An instance of IObjectNameGenerator or NULL if no instance can be created</returns>
|
||||
public static IObjectNameGenerator GetNameGenerator(string expression)
|
||||
{
|
||||
return GetCustomType(expression) as IObjectNameGenerator;
|
||||
}
|
||||
|
||||
private static object GetCustomType(string expression)
|
||||
{
|
||||
var customTypeFilterType = LoadType(expression);
|
||||
if (customTypeFilterType == null)
|
||||
return null;
|
||||
|
||||
try
|
||||
{
|
||||
var instance = ObjectUtils.InstantiateType(customTypeFilterType);
|
||||
return instance;
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logger.Error(string.Format("Can't instatiate {0}. Type needs to have a non arg constructor.", expression));
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static Type LoadType(string typeToLoad)
|
||||
{
|
||||
try
|
||||
{
|
||||
return TypeResolutionUtils.ResolveType(typeToLoad);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
Logger.Error("Can't load type defined in exoression:" + typeToLoad);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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;
|
||||
|
||||
namespace Spring.Context.Attributes.TypeFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the base interface for all component-scan type filters
|
||||
/// </summary>
|
||||
public interface ITypeFilter
|
||||
{
|
||||
/// <summary>
|
||||
/// Determine a match based on the given type object.
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns>true if there is a match; false is there is no match</returns>
|
||||
bool Match(Type type);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Text.RegularExpressions;
|
||||
|
||||
namespace Spring.Context.Attributes.TypeFilters
|
||||
{
|
||||
/// <summary>
|
||||
/// A simple filter for matching a fully-qualified class name with a regex
|
||||
/// </summary>
|
||||
public class RegexPatternTypeFilter : ITypeFilter
|
||||
{
|
||||
private string _pattern;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Creates a type filter with provided pattern
|
||||
/// </summary>
|
||||
/// <param name="pattern">Regex pattern</param>
|
||||
public RegexPatternTypeFilter(string pattern)
|
||||
{
|
||||
_pattern = pattern;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine a match based on the given type object.
|
||||
/// </summary>
|
||||
/// <param name="type">Type to compare against</param>
|
||||
/// <returns>true if there is a match; false is there is no match</returns>
|
||||
public bool Match(Type type)
|
||||
{
|
||||
return Regex.IsMatch(type.FullName, _pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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.Xml;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Object Defintion Parser for interpreting <see cref="ConfigurationAttribute"/> classes when primary configuration is peformed via XML.
|
||||
/// </summary>
|
||||
public class AttributeConfigObjectDefinitionParser : IObjectDefinitionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// Parse the specified XmlElement and register the resulting
|
||||
/// ObjectDefinitions with the <see cref="P:Spring.Objects.Factory.Xml.ParserContext.Registry"/> IObjectDefinitionRegistry
|
||||
/// embedded in the supplied <see cref="T:Spring.Objects.Factory.Xml.ParserContext"/>
|
||||
/// </summary>
|
||||
/// <param name="element">The element to be parsed.</param>
|
||||
/// <param name="parserContext">TThe object encapsulating the current state of the parsing process.
|
||||
/// Provides access to a IObjectDefinitionRegistry</param>
|
||||
/// <returns>The primary object definition.</returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is never invoked if the parser is namespace aware
|
||||
/// and was called to process the root node.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
IObjectDefinitionRegistry registry = parserContext.ReaderContext.Registry;
|
||||
AssertUtils.ArgumentNotNull(registry, "registry");
|
||||
|
||||
AttributeConfigUtils.RegisterAttributeConfigProcessors(registry);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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.ComponentModel;
|
||||
using System.Xml;
|
||||
using Common.Logging;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Context.Attributes.TypeFilters;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// Parses ObjectDefinitions from classes identified by an <see cref="AssemblyObjectDefinitionScanner"/>.
|
||||
/// </summary>
|
||||
public class ComponentScanObjectDefinitionParser : IObjectDefinitionParser
|
||||
{
|
||||
private static readonly ILog Logger = LogManager.GetLogger<ComponentScanObjectDefinitionParser>();
|
||||
|
||||
private const string ATTRIBUTE_CONFIG_ATTRIBUTE = "attribute-config";
|
||||
|
||||
private const string NAME_GENERATOR_ATTRIBUTE = "name-generator";
|
||||
|
||||
private const string BASE_ASSEMBLIES_ATTRIBUTE = "base-assemblies";
|
||||
|
||||
private const string EXCLUDE_FILTER_ELEMENT = "exclude-filter";
|
||||
|
||||
private const string INCLUDE_FILTER_ELEMENT = "include-filter";
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Parse the specified XmlElement and register the resulting
|
||||
/// ObjectDefinitions with the <see cref="P:Spring.Objects.Factory.Xml.ParserContext.Registry"/> IObjectDefinitionRegistry
|
||||
/// embedded in the supplied <see cref="T:Spring.Objects.Factory.Xml.ParserContext"/>
|
||||
/// </summary>
|
||||
/// <param name="element">The element to be parsed.</param>
|
||||
/// <param name="parserContext">TThe object encapsulating the current state of the parsing process.
|
||||
/// Provides access to a IObjectDefinitionRegistry</param>
|
||||
/// <returns>The primary object definition.</returns>
|
||||
/// <remarks>
|
||||
/// <p>
|
||||
/// This method is never invoked if the parser is namespace aware
|
||||
/// and was called to process the root node.
|
||||
/// </p>
|
||||
/// </remarks>
|
||||
public IObjectDefinition ParseElement(XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
AssemblyObjectDefinitionScanner scanner = ConfigureScanner(parserContext, element);
|
||||
IObjectDefinitionRegistry registry = parserContext.Registry;
|
||||
|
||||
// Actually scan for objects definitions and register them.
|
||||
scanner.ScanAndRegisterTypes(registry);
|
||||
RegisterComponents(element, registry);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Configures the scanner.
|
||||
/// </summary>
|
||||
/// <param name="parserContext">The parser context.</param>
|
||||
/// <param name="element">The element.</param>
|
||||
/// <returns></returns>
|
||||
protected virtual AssemblyObjectDefinitionScanner ConfigureScanner(ParserContext parserContext, XmlElement element)
|
||||
{
|
||||
var scanner = new AssemblyObjectDefinitionScanner();
|
||||
|
||||
ParseBaseAssembliesAttribute(scanner, element);
|
||||
ParseNameGeneratorAttribute(scanner, element);
|
||||
ParseTypeFilters(scanner, element);
|
||||
|
||||
scanner.Defaults = parserContext.ParserHelper.Defaults;
|
||||
|
||||
return scanner;
|
||||
}
|
||||
|
||||
private void ParseBaseAssembliesAttribute(AssemblyObjectDefinitionScanner scanner, XmlElement element)
|
||||
{
|
||||
var baseAssemblies = element.GetAttribute(BASE_ASSEMBLIES_ATTRIBUTE);
|
||||
|
||||
if (string.IsNullOrEmpty(baseAssemblies))
|
||||
return;
|
||||
|
||||
foreach (var baseAssembly in baseAssemblies.Split(','))
|
||||
{
|
||||
scanner.WithAssemblyFilter(assy => assy.FullName.StartsWith(baseAssembly));
|
||||
}
|
||||
}
|
||||
|
||||
private void ParseNameGeneratorAttribute(AssemblyObjectDefinitionScanner scanner, XmlElement element)
|
||||
{
|
||||
var nameGeneratorString = element.GetAttribute(NAME_GENERATOR_ATTRIBUTE);
|
||||
var nameGenerator = CustomTypeFactory.GetNameGenerator(nameGeneratorString);
|
||||
if (nameGenerator != null)
|
||||
scanner.ObjectNameGenerator = nameGenerator;
|
||||
}
|
||||
|
||||
private void ParseTypeFilters(AssemblyObjectDefinitionScanner scanner, XmlElement element)
|
||||
{
|
||||
foreach (XmlNode node in element.ChildNodes)
|
||||
{
|
||||
if (node.Name.Contains(INCLUDE_FILTER_ELEMENT))
|
||||
scanner.WithIncludeFilter(CreateTypeFilter(node));
|
||||
else if (node.Name.Contains(EXCLUDE_FILTER_ELEMENT))
|
||||
scanner.WithExcludeFilter(CreateTypeFilter(node));
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterComponents(XmlElement element, IObjectDefinitionRegistry registry)
|
||||
{
|
||||
bool attributeConfig = true;
|
||||
var attr = element.GetAttribute(ATTRIBUTE_CONFIG_ATTRIBUTE);
|
||||
if (attr != null)
|
||||
bool.TryParse(attr, out attributeConfig);
|
||||
if (attributeConfig)
|
||||
AttributeConfigUtils.RegisterAttributeConfigProcessors(registry);
|
||||
}
|
||||
|
||||
private ITypeFilter CreateTypeFilter(XmlNode node)
|
||||
{
|
||||
var type = node.Attributes["type"].Value;
|
||||
var expression = node.Attributes["expression"].Value;
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case "regex":
|
||||
return new RegexPatternTypeFilter(expression);
|
||||
case "attribute":
|
||||
return new AttributeTypeFilter(expression);
|
||||
case "assignable":
|
||||
return new AssignableTypeFilter(expression);
|
||||
case "custom":
|
||||
return CustomTypeFactory.GetTypeFilter(expression);
|
||||
default:
|
||||
throw new InvalidEnumArgumentException(string.Format("Filter type {0} is not defined", type));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 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><tx:advice></code> elements, the other uses attributes
|
||||
/// in combination with the <code><tx:annotation-driven></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-2.0.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());
|
||||
}
|
||||
}
|
||||
}
|
||||
43
src/Spring/Spring.Core/Context/Config/spring-context-1.3.xsd
Normal file
43
src/Spring/Spring.Core/Context/Config/spring-context-1.3.xsd
Normal file
@@ -0,0 +1,43 @@
|
||||
<?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="code-config">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Scans assemblies for [Configuration] attributes that provide Spring object definitions.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<!--
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="assemblies" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The names of assemblies to be scanned.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
-->
|
||||
</xsd:element>
|
||||
|
||||
|
||||
</xsd:schema>
|
||||
154
src/Spring/Spring.Core/Context/Config/spring-context-2.0.xsd
Normal file
154
src/Spring/Spring.Core/Context/Config/spring-context-2.0.xsd
Normal file
@@ -0,0 +1,154 @@
|
||||
<?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 attributes to be detected in object classes: Spring's [Required],
|
||||
[Autowired], [Value] as well [PostConstruct], [PreDestroy]. Alternatively, you may
|
||||
choose to activate the individual BeanPostProcessors for those annotations.
|
||||
|
||||
Note: This tag does not activate processing of Spring's [Transactional].
|
||||
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 assemblies for attributed components that will be auto-registered as
|
||||
Spring objects. By default, the Spring-provided [Component], [Repository],
|
||||
[Service], and [Controller] stereotypes will be detected.
|
||||
|
||||
Note: This tag implies the effects of the 'attribute-config' tag, activating [Required],
|
||||
[Autowired], [PostConstruct], [PreDestroy]
|
||||
attributes 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 ObjectPostProcessor 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:sequence>
|
||||
<xsd:element name="include-filter" type="filterType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Controls which eligible types to include for component scanning.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
<xsd:element name="exclude-filter" type="filterType" minOccurs="0" maxOccurs="unbounded">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Controls which eligible types to exclude for component scanning.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="base-assemblies" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
The comma-separated list of assemblies to scan for attributed components.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="attribute-config" type="xsd:boolean" default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Indicates if attribte driven post processors will be registered, 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:appinfo>
|
||||
<tool:annotation>
|
||||
<tool:expected-type type="java.lang.Class" />
|
||||
<tool:assignable-to
|
||||
type="org.springframework.beans.factory.support.BeanNameGenerator" />
|
||||
</tool:annotation>
|
||||
</xsd:appinfo>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:complexType name="filterType">
|
||||
<xsd:attribute name="type" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Controls the type of filtering to apply to the expression.
|
||||
|
||||
"attribute" indicates an attribute to be present or excluded at the type level in target components;
|
||||
"assignable" indicates a class (or interface) that the target components are assignable to (extend/implement);
|
||||
"regex" indicates a regex expression to be matched by the target components' class names;
|
||||
|
||||
Note: This attribute will not be inherited by child bean definitions.
|
||||
Hence, it needs to be specified per concrete bean definition.
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:simpleType>
|
||||
<xsd:restriction base="xsd:string">
|
||||
<xsd:enumeration value="assignable" />
|
||||
<xsd:enumeration value="attribute" />
|
||||
<xsd:enumeration value="custom" />
|
||||
<xsd:enumeration value="regex" />
|
||||
</xsd:restriction>
|
||||
</xsd:simpleType>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="expression" type="xsd:string" use="required">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation>
|
||||
<![CDATA[
|
||||
Indicates the filter expression, the type of which is indicated by "type".
|
||||
]]>
|
||||
</xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
|
||||
</xsd:schema>
|
||||
@@ -0,0 +1,110 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Context.Attributes;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// Extensions to enable scanning on any AbstractApplicationContext-derived type.
|
||||
/// </summary>
|
||||
public static class GenericApplicationContextExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Scans for types using the provided scanner.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="scanner">The scanner.</param>
|
||||
public static void Scan(this GenericApplicationContext context, AssemblyObjectDefinitionScanner scanner)
|
||||
{
|
||||
var registry = context.ObjectFactory as IObjectDefinitionRegistry;
|
||||
scanner.ScanAndRegisterTypes(registry);
|
||||
|
||||
AttributeConfigUtils.RegisterAttributeConfigProcessors(registry);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans for types that satisfy specified predicates located in the specified scan path.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="assemblyScanPath">The assembly scan path.</param>
|
||||
/// <param name="assemblyPredicate">The assembly predicate.</param>
|
||||
/// <param name="typePredicate">The type predicate.</param>
|
||||
public static void Scan(this GenericApplicationContext context, string assemblyScanPath, Predicate<Assembly> assemblyPredicate,
|
||||
Predicate<Type> typePredicate)
|
||||
{
|
||||
//create a scanner instance using the scan path
|
||||
var scanner = new AssemblyObjectDefinitionScanner();
|
||||
|
||||
//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(context, scanner);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans for types that satisfy specified predicates.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="assemblyPredicate">The assembly predicate.</param>
|
||||
/// <param name="typePredicate">The type predicate.</param>
|
||||
public static void Scan(this GenericApplicationContext context, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
|
||||
{
|
||||
Scan(context, null, assemblyPredicate, typePredicate);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans for types using the default scanner.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
public static void ScanAllAssemblies(this GenericApplicationContext context)
|
||||
{
|
||||
Scan(context, new AssemblyObjectDefinitionScanner());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Scans the with assembly filter.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="assemblyPredicate">The assembly predicate.</param>
|
||||
public static void ScanWithAssemblyFilter(this GenericApplicationContext context, Predicate<Assembly> assemblyPredicate)
|
||||
{
|
||||
Scan(context, null, assemblyPredicate, delegate { return true; });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Scans the with type filter.
|
||||
/// </summary>
|
||||
/// <param name="context">The context.</param>
|
||||
/// <param name="typePredicate">The type predicate.</param>
|
||||
public static void ScanWithTypeFilter(this GenericApplicationContext context, Predicate<Type> typePredicate)
|
||||
{
|
||||
Scan(context, null, delegate { return true; }, typePredicate);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Support
|
||||
{
|
||||
/// <summary>
|
||||
/// ApplicationContext that can scan to identify object definitions
|
||||
/// </summary>
|
||||
public class CodeConfigApplicationContext : GenericApplicationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
public CodeConfigApplicationContext()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="caseSensitive">if set to <c>true</c> names in the context are case sensitive.</param>
|
||||
public CodeConfigApplicationContext(bool caseSensitive)
|
||||
: base(caseSensitive)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory">The object factory instance to use for this context.</param>
|
||||
public CodeConfigApplicationContext(DefaultListableObjectFactory objectFactory)
|
||||
: base(objectFactory)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="parent">The parent application context.</param>
|
||||
public CodeConfigApplicationContext(IApplicationContext parent)
|
||||
: base(parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the application context.</param><param name="caseSensitive">if set to <c>true</c> names in the context are case sensitive.</param><param name="parent">The parent application context.</param>
|
||||
public CodeConfigApplicationContext(string name, bool caseSensitive, IApplicationContext parent)
|
||||
: base(name, caseSensitive, parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="objectFactory">The object factory to use for this context</param><param name="parent">The parent applicaiton context.</param>
|
||||
public CodeConfigApplicationContext(DefaultListableObjectFactory objectFactory, IApplicationContext parent)
|
||||
: base(objectFactory, parent)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="T:Spring.Context.Support.GenericApplicationContext"/> class.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the application context.</param><param name="caseSensitive">if set to <c>true</c> names in the context are case sensitive.</param><param name="parent">The parent application context.</param><param name="objectFactory">The object factory to use for this context</param>
|
||||
public CodeConfigApplicationContext(string name, bool caseSensitive, IApplicationContext parent,
|
||||
DefaultListableObjectFactory objectFactory)
|
||||
: base(name, caseSensitive, parent, objectFactory)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -177,6 +177,39 @@
|
||||
<Compile Include="Context\ApplicationEventArgs.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Context\Attributes\AssemblyObjectDefinitionScanner.cs" />
|
||||
<Compile Include="Context\Attributes\AssemblyTypeScanner.cs" />
|
||||
<Compile Include="Context\Attributes\AssemblyTypeSource.cs" />
|
||||
<Compile Include="Context\Attributes\AttributeConfigUtils.cs" />
|
||||
<Compile Include="Context\Attributes\AttributeObjectNameGenerator.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClass.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassAssemblyResource.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassEnhancer.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\DependsOnAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\IAssemblyTypeScanner.cs" />
|
||||
<Compile Include="Context\Attributes\ImportAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ImportResourceAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\LazyAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\LinqExtensionMethods.cs" />
|
||||
<Compile Include="Context\Attributes\ObjectDefAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ReflectionOnlyUtils.cs" />
|
||||
<Compile Include="Context\Attributes\RequiredConstraintAssemblyTypeScanner.cs" />
|
||||
<Compile Include="Context\Attributes\ScannedGenericObjectDefinition.cs" />
|
||||
<Compile Include="Context\Attributes\ScopeAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\TypeFilters\AbstractLoadTypeFilter.cs" />
|
||||
<Compile Include="Context\Attributes\TypeFilters\AssignableTypeFilter.cs" />
|
||||
<Compile Include="Context\Attributes\TypeFilters\AttributeTypeFilter.cs" />
|
||||
<Compile Include="Context\Attributes\TypeFilters\CustomTypeFactory.cs" />
|
||||
<Compile Include="Context\Attributes\TypeFilters\ITypeFilter.cs" />
|
||||
<Compile Include="Context\Attributes\TypeFilters\RegexPatternTypeFilter.cs" />
|
||||
<Compile Include="Context\Config\AttributeConfigObjectDefinitionParser.cs" />
|
||||
<Compile Include="Context\Config\ComponentScanObjectDefinitionParser.cs" />
|
||||
<Compile Include="Context\Config\ContextNamespaceParser.cs" />
|
||||
<Compile Include="Context\EventListenerAttribute.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -186,6 +219,7 @@
|
||||
<Compile Include="Context\Events\ContextEventArgs.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Context\Extension\GenericApplicationContextExtensions.cs" />
|
||||
<Compile Include="Context\IApplicationContext.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -234,6 +268,7 @@
|
||||
<Compile Include="Context\Support\ApplicationObjectSupport.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Context\Support\CodeConfigApplicationContext.cs" />
|
||||
<Compile Include="Context\Support\ContextHandler.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -1239,6 +1274,12 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<None Include="ContextClassDiagram.cd" />
|
||||
<EmbeddedResource Include="Context\Config\spring-context-1.3.xsd">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<EmbeddedResource Include="Context\Config\spring-context-2.0.xsd">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
<None Include="Expressions\Expression.g" />
|
||||
<EmbeddedResource Include="Objects\Factory\Xml\spring-tool-1.1.xsd">
|
||||
<SubType>
|
||||
|
||||
@@ -128,62 +128,6 @@
|
||||
Create a new session on demand
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings">
|
||||
<summary>
|
||||
Setting for <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/>
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="F:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.FLUSHMODE_DEFAULT">
|
||||
<summary>
|
||||
Default value for <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode"/> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor">
|
||||
<summary>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionScopeSettings"/> with default values.
|
||||
</summary>
|
||||
<remarks>
|
||||
Calling this constructor from your derived class leaves <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor"/>
|
||||
uninitialized. See <see cref="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor"/> for more.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor(NHibernate.IInterceptor,NHibernate.FlushMode)">
|
||||
<summary>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings"/> with the given values and references.
|
||||
</summary>
|
||||
<param name="entityInterceptor">
|
||||
Specify the <see cref="T:NHibernate.IInterceptor"/> to be set on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/> instance.
|
||||
</param>
|
||||
<param name="defaultFlushMode">
|
||||
Specify the flushmode to be applied on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionScope"/> instance.
|
||||
</param>
|
||||
<remarks>
|
||||
Calling this constructor marks all properties initialized.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor">
|
||||
<summary>
|
||||
Override this method to resolve an <see cref="T:NHibernate.IInterceptor"/> instance according to your chosen strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor">
|
||||
<summary>
|
||||
Gets the configured <see cref="T:NHibernate.IInterceptor"/> instance to be used.
|
||||
</summary>
|
||||
<remarks>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode">
|
||||
<summary>
|
||||
Gets or Sets the flushmode to be applied on each newly created session.
|
||||
</summary>
|
||||
<remarks>
|
||||
This property defaults to <see cref="F:NHibernate.FlushMode.Never"/> to ensure that modifying objects outside the boundaries
|
||||
of a transaction will not be persisted. It is recommended to not change this value but wrap any modifying operation
|
||||
within a transaction.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.IConversationState">
|
||||
<summary>
|
||||
Port to conversation. If the object is not found in the current
|
||||
@@ -867,6 +811,62 @@
|
||||
Returns the current context. Supports serialization and deserialization.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings">
|
||||
<summary>
|
||||
Setting for <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/>
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="F:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.FLUSHMODE_DEFAULT">
|
||||
<summary>
|
||||
Default value for <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode"/> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor">
|
||||
<summary>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionScopeSettings"/> with default values.
|
||||
</summary>
|
||||
<remarks>
|
||||
Calling this constructor from your derived class leaves <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor"/>
|
||||
uninitialized. See <see cref="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor"/> for more.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor(NHibernate.IInterceptor,NHibernate.FlushMode)">
|
||||
<summary>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings"/> with the given values and references.
|
||||
</summary>
|
||||
<param name="entityInterceptor">
|
||||
Specify the <see cref="T:NHibernate.IInterceptor"/> to be set on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/> instance.
|
||||
</param>
|
||||
<param name="defaultFlushMode">
|
||||
Specify the flushmode to be applied on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionScope"/> instance.
|
||||
</param>
|
||||
<remarks>
|
||||
Calling this constructor marks all properties initialized.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor">
|
||||
<summary>
|
||||
Override this method to resolve an <see cref="T:NHibernate.IInterceptor"/> instance according to your chosen strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor">
|
||||
<summary>
|
||||
Gets the configured <see cref="T:NHibernate.IInterceptor"/> instance to be used.
|
||||
</summary>
|
||||
<remarks>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode">
|
||||
<summary>
|
||||
Gets or Sets the flushmode to be applied on each newly created session.
|
||||
</summary>
|
||||
<remarks>
|
||||
This property defaults to <see cref="F:NHibernate.FlushMode.Never"/> to ensure that modifying objects outside the boundaries
|
||||
of a transaction will not be persisted. It is recommended to not change this value but wrap any modifying operation
|
||||
within a transaction.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.WebConversationManager">
|
||||
<summary>
|
||||
This was made to stay under session scope.
|
||||
|
||||
@@ -128,146 +128,6 @@
|
||||
Create a new session on demand
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings">
|
||||
<summary>
|
||||
Setting for <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/>
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="F:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.FLUSHMODE_DEFAULT">
|
||||
<summary>
|
||||
Default value for <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode"/> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor">
|
||||
<summary>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionScopeSettings"/> with default values.
|
||||
</summary>
|
||||
<remarks>
|
||||
Calling this constructor from your derived class leaves <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor"/>
|
||||
uninitialized. See <see cref="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor"/> for more.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor(NHibernate.IInterceptor,NHibernate.FlushMode)">
|
||||
<summary>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings"/> with the given values and references.
|
||||
</summary>
|
||||
<param name="entityInterceptor">
|
||||
Specify the <see cref="T:NHibernate.IInterceptor"/> to be set on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/> instance.
|
||||
</param>
|
||||
<param name="defaultFlushMode">
|
||||
Specify the flushmode to be applied on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionScope"/> instance.
|
||||
</param>
|
||||
<remarks>
|
||||
Calling this constructor marks all properties initialized.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor">
|
||||
<summary>
|
||||
Override this method to resolve an <see cref="T:NHibernate.IInterceptor"/> instance according to your chosen strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor">
|
||||
<summary>
|
||||
Gets the configured <see cref="T:NHibernate.IInterceptor"/> instance to be used.
|
||||
</summary>
|
||||
<remarks>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode">
|
||||
<summary>
|
||||
Gets or Sets the flushmode to be applied on each newly created session.
|
||||
</summary>
|
||||
<remarks>
|
||||
This property defaults to <see cref="F:NHibernate.FlushMode.Never"/> to ensure that modifying objects outside the boundaries
|
||||
of a transaction will not be persisted. It is recommended to not change this value but wrap any modifying operation
|
||||
within a transaction.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.IConversationManager">
|
||||
<summary>
|
||||
manager for Conversations.
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.GetConversationById(System.String)">
|
||||
<summary>
|
||||
Returns the conversation if it is still alive, otherwise it returns null.
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.EndOnTimeOut">
|
||||
<summary>
|
||||
Ends all conversations with the timeout exceeded.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.PauseConversations">
|
||||
<summary>
|
||||
Close IDbConnections for <see cref="T:Spring.Web.Conversation.IConversationState"/> that
|
||||
use 'session-per-conversation'. It calls
|
||||
<see cref="M:Spring.Web.Conversation.IConversationState.PauseConversation"/> in all conversations.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.FreeEnded">
|
||||
<summary>
|
||||
Release the ended conversations And removes them.
|
||||
If the conversation supports 'session-per-conversation', also close the session.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.AddConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
Add conversation. If <see cref="T:Spring.Web.Conversation.IConversationManager"/> is null
|
||||
it resolves to 'this'.
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
<exception cref="T:System.InvalidOperationException">
|
||||
If <paramref name="conversation"/> already has another manager.
|
||||
</exception>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.SetActiveConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
Makes the 'root conversation' of <paramref name="conversation"/>
|
||||
the current active conversation and open/reopen the
|
||||
<see cref="P:Spring.Web.Conversation.IConversationState.RootSessionPerConversation"/> if
|
||||
the conversation supports 'session-per-conversation'. Close all
|
||||
the connection for all session before.
|
||||
If <see cref="P:Spring.Web.Conversation.IConversationManager.EndPaused"/> is <c>true</c> will end all
|
||||
paused conversations.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.IConversationManager.ActiveConversation">
|
||||
<summary>
|
||||
Returns the active conversation if exists, otherwise returns null.
|
||||
It depends on <see cref="M:Spring.Web.Conversation.IConversationManager.SetActiveConversation(Spring.Web.Conversation.IConversationState)"/>
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.IConversationManager.SessionFactory">
|
||||
<summary>
|
||||
<para>If this is non-null run pattern 'session-per-conversation'.
|
||||
Must be the same SessionFactory of the managed conversations.
|
||||
</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.IConversationManager.EndPaused">
|
||||
<summary>
|
||||
Ends the "paused conversations" in call to <see cref="P:Spring.Web.Conversation.IConversationManager.ActiveConversation"/>.
|
||||
Important: Unexpected behavior may occur if there are nested conversations,
|
||||
as in <see cref="M:Spring.Web.Conversation.IConversationState.StartResumeConversation"/> only the current conversation and its parents
|
||||
are started, the 'conversations children' remain paused, so these will be ended.
|
||||
Defaul value: <c>false</c>.
|
||||
</summary>
|
||||
<remarks>
|
||||
<para>When it is true, "start/resume a conversation" will cause the other to be
|
||||
ended and cleaned up.
|
||||
</para>
|
||||
<para>This is useful to avoid memory leak where there are many conversations.
|
||||
This leak can be very considerable, as the conversation may keep a "NHibernate session"
|
||||
that can contain many objects in its cache from the database queries.
|
||||
</para>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.IConversationState">
|
||||
<summary>
|
||||
Port to conversation. If the object is not found in the current
|
||||
@@ -423,6 +283,151 @@
|
||||
Indicates that the conversation is paused.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.IConversationManager">
|
||||
<summary>
|
||||
manager for Conversations.
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.GetConversationById(System.String)">
|
||||
<summary>
|
||||
Returns the conversation if it is still alive, otherwise it returns null.
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.EndOnTimeOut">
|
||||
<summary>
|
||||
Ends all conversations with the timeout exceeded.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.PauseConversations">
|
||||
<summary>
|
||||
Close IDbConnections for <see cref="T:Spring.Web.Conversation.IConversationState"/> that
|
||||
use 'session-per-conversation'. It calls
|
||||
<see cref="M:Spring.Web.Conversation.IConversationState.PauseConversation"/> in all conversations.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.FreeEnded">
|
||||
<summary>
|
||||
Release the ended conversations And removes them.
|
||||
If the conversation supports 'session-per-conversation', also close the session.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.AddConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
Add conversation. If <see cref="T:Spring.Web.Conversation.IConversationManager"/> is null
|
||||
it resolves to 'this'.
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
<exception cref="T:System.InvalidOperationException">
|
||||
If <paramref name="conversation"/> already has another manager.
|
||||
</exception>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.IConversationManager.SetActiveConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
Makes the 'root conversation' of <paramref name="conversation"/>
|
||||
the current active conversation and open/reopen the
|
||||
<see cref="P:Spring.Web.Conversation.IConversationState.RootSessionPerConversation"/> if
|
||||
the conversation supports 'session-per-conversation'. Close all
|
||||
the connection for all session before.
|
||||
If <see cref="P:Spring.Web.Conversation.IConversationManager.EndPaused"/> is <c>true</c> will end all
|
||||
paused conversations.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.IConversationManager.ActiveConversation">
|
||||
<summary>
|
||||
Returns the active conversation if exists, otherwise returns null.
|
||||
It depends on <see cref="M:Spring.Web.Conversation.IConversationManager.SetActiveConversation(Spring.Web.Conversation.IConversationState)"/>
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.IConversationManager.SessionFactory">
|
||||
<summary>
|
||||
<para>If this is non-null run pattern 'session-per-conversation'.
|
||||
Must be the same SessionFactory of the managed conversations.
|
||||
</para>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.IConversationManager.EndPaused">
|
||||
<summary>
|
||||
Ends the "paused conversations" in call to <see cref="P:Spring.Web.Conversation.IConversationManager.ActiveConversation"/>.
|
||||
Important: Unexpected behavior may occur if there are nested conversations,
|
||||
as in <see cref="M:Spring.Web.Conversation.IConversationState.StartResumeConversation"/> only the current conversation and its parents
|
||||
are started, the 'conversations children' remain paused, so these will be ended.
|
||||
Defaul value: <c>false</c>.
|
||||
</summary>
|
||||
<remarks>
|
||||
<para>When it is true, "start/resume a conversation" will cause the other to be
|
||||
ended and cleaned up.
|
||||
</para>
|
||||
<para>This is useful to avoid memory leak where there are many conversations.
|
||||
This leak can be very considerable, as the conversation may keep a "NHibernate session"
|
||||
that can contain many objects in its cache from the database queries.
|
||||
</para>
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.HttpModule.ConversationModule">
|
||||
<summary>
|
||||
HttpModule for ending Conversations with Timeout exceeded.
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.HttpModule.ConversationModule.Init(System.Web.HttpApplication)">
|
||||
<summary>
|
||||
Add PostRequestHandlerExecute event to clear conversations with timeout exceeded.
|
||||
</summary>
|
||||
<param name="context"></param>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.HttpModule.ConversationModule.Dispose">
|
||||
<summary>
|
||||
Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.HttpModule.ConversationModule.page_Unload(System.Object,System.EventArgs)">
|
||||
<summary>
|
||||
Handles the Unload event of the page control.
|
||||
</summary>
|
||||
<param name="sender">The source of the event.</param>
|
||||
<param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
|
||||
<remarks>
|
||||
Necessary for Redirect or Abort for any reason.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.HttpModule.ConversationModule.ConversationManagerNameList">
|
||||
<summary>
|
||||
The Names of the <see cref="T:Spring.Web.Conversation.IConversationManager"/>s in the <see cref="T:Spring.Context.IApplicationContext"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.HttpModule.ConversationModule.ApplicationContext">
|
||||
<summary>
|
||||
Sets the <see cref="T:Spring.Context.IApplicationContext"/> that this
|
||||
object runs in.
|
||||
</summary>
|
||||
<value></value>
|
||||
<remarks>
|
||||
<p>
|
||||
Used to obtain the instances of <see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</p>
|
||||
<p>
|
||||
Invoked after population of normal object properties but before an
|
||||
init callback such as
|
||||
<see cref="T:Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
<see cref="M:Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
or a custom init-method. Invoked after the setting of any
|
||||
<see cref="T:Spring.Context.IResourceLoaderAware"/>'s
|
||||
<see cref="P:Spring.Context.IResourceLoaderAware.ResourceLoader"/>
|
||||
property.
|
||||
</p>
|
||||
</remarks>
|
||||
<exception cref="T:Spring.Context.ApplicationContextException">
|
||||
In the case of application context initialization errors.
|
||||
</exception>
|
||||
<exception cref="T:Spring.Objects.ObjectsException">
|
||||
If thrown by any application context methods.
|
||||
</exception>
|
||||
<exception cref="T:Spring.Objects.Factory.ObjectInitializationException"/>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.InnerConversationList">
|
||||
<summary>
|
||||
List that make validation for Circular Dependency for <see cref="T:Spring.Web.Conversation.IConversationState"/>
|
||||
@@ -590,93 +595,6 @@
|
||||
<see cref="T:System.Collections.ICollection"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.WebConversationManager">
|
||||
<summary>
|
||||
This was made to stay under session scope.
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="F:Spring.Web.Conversation.WebConversationManager.mutexEditDic">
|
||||
<summary>
|
||||
Semaphore to synchronize writes to the dictionary.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.GetConversationById(System.String)">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.EndOnTimeOut">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.PauseConversations">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.FreeEnded">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.AddConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.SetActiveConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.LoadActiveConversation">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.Dispose">
|
||||
<summary>
|
||||
Ends all conversations and Closes all their Session.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.RemoveConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
Remove conversation.
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.ActiveConversation">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.SessionFactoryName">
|
||||
<summary>
|
||||
"SessionFactory" name in the current context.
|
||||
This approach is required to support serialization.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.SessionFactory">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.EndPaused">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.ApplicationContext">
|
||||
<summary>
|
||||
Returns the current context. Supports serialization and deserialization.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.WebConversationSpringState">
|
||||
<summary>
|
||||
Implementation of conversation in the infrastructure of Spring.
|
||||
@@ -893,66 +811,148 @@
|
||||
Returns the current context. Supports serialization and deserialization.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.HttpModule.ConversationModule">
|
||||
<member name="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings">
|
||||
<summary>
|
||||
HttpModule for ending Conversations with Timeout exceeded.
|
||||
Setting for <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/>
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.HttpModule.ConversationModule.Init(System.Web.HttpApplication)">
|
||||
<member name="F:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.FLUSHMODE_DEFAULT">
|
||||
<summary>
|
||||
Add PostRequestHandlerExecute event to clear conversations with timeout exceeded.
|
||||
</summary>
|
||||
<param name="context"></param>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.HttpModule.ConversationModule.Dispose">
|
||||
<summary>
|
||||
Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
|
||||
Default value for <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode"/> property.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.HttpModule.ConversationModule.page_Unload(System.Object,System.EventArgs)">
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor">
|
||||
<summary>
|
||||
Handles the Unload event of the page control.
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionScopeSettings"/> with default values.
|
||||
</summary>
|
||||
<param name="sender">The source of the event.</param>
|
||||
<param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
|
||||
<remarks>
|
||||
Necessary for Redirect or Abort for any reason.
|
||||
Calling this constructor from your derived class leaves <see cref="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor"/>
|
||||
uninitialized. See <see cref="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor"/> for more.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.HttpModule.ConversationModule.ConversationManagerNameList">
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.#ctor(NHibernate.IInterceptor,NHibernate.FlushMode)">
|
||||
<summary>
|
||||
The Names of the <see cref="T:Spring.Web.Conversation.IConversationManager"/>s in the <see cref="T:Spring.Context.IApplicationContext"/>
|
||||
Initialize a new instance of <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings"/> with the given values and references.
|
||||
</summary>
|
||||
<param name="entityInterceptor">
|
||||
Specify the <see cref="T:NHibernate.IInterceptor"/> to be set on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionPerConversationScope"/> instance.
|
||||
</param>
|
||||
<param name="defaultFlushMode">
|
||||
Specify the flushmode to be applied on each session provided by the <see cref="T:Spring.Data.NHibernate.Support.SessionScope"/> instance.
|
||||
</param>
|
||||
<remarks>
|
||||
Calling this constructor marks all properties initialized.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="M:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.ResolveEntityInterceptor">
|
||||
<summary>
|
||||
Override this method to resolve an <see cref="T:NHibernate.IInterceptor"/> instance according to your chosen strategy.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.HttpModule.ConversationModule.ApplicationContext">
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.EntityInterceptor">
|
||||
<summary>
|
||||
Sets the <see cref="T:Spring.Context.IApplicationContext"/> that this
|
||||
object runs in.
|
||||
Gets the configured <see cref="T:NHibernate.IInterceptor"/> instance to be used.
|
||||
</summary>
|
||||
<value></value>
|
||||
<remarks>
|
||||
<p>
|
||||
Used to obtain the instances of <see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</p>
|
||||
<p>
|
||||
Invoked after population of normal object properties but before an
|
||||
init callback such as
|
||||
<see cref="T:Spring.Objects.Factory.IInitializingObject"/>'s
|
||||
<see cref="M:Spring.Objects.Factory.IInitializingObject.AfterPropertiesSet"/>
|
||||
or a custom init-method. Invoked after the setting of any
|
||||
<see cref="T:Spring.Context.IResourceLoaderAware"/>'s
|
||||
<see cref="P:Spring.Context.IResourceLoaderAware.ResourceLoader"/>
|
||||
property.
|
||||
</p>
|
||||
</remarks>
|
||||
<exception cref="T:Spring.Context.ApplicationContextException">
|
||||
In the case of application context initialization errors.
|
||||
</exception>
|
||||
<exception cref="T:Spring.Objects.ObjectsException">
|
||||
If thrown by any application context methods.
|
||||
</exception>
|
||||
<exception cref="T:Spring.Objects.Factory.ObjectInitializationException"/>
|
||||
</member>
|
||||
<member name="P:Spring.Data.NHibernate.Support.SessionPerConversationScopeSettings.DefaultFlushMode">
|
||||
<summary>
|
||||
Gets or Sets the flushmode to be applied on each newly created session.
|
||||
</summary>
|
||||
<remarks>
|
||||
This property defaults to <see cref="F:NHibernate.FlushMode.Never"/> to ensure that modifying objects outside the boundaries
|
||||
of a transaction will not be persisted. It is recommended to not change this value but wrap any modifying operation
|
||||
within a transaction.
|
||||
</remarks>
|
||||
</member>
|
||||
<member name="T:Spring.Web.Conversation.WebConversationManager">
|
||||
<summary>
|
||||
This was made to stay under session scope.
|
||||
</summary>
|
||||
<author>Hailton de Castro</author>
|
||||
</member>
|
||||
<member name="F:Spring.Web.Conversation.WebConversationManager.mutexEditDic">
|
||||
<summary>
|
||||
Semaphore to synchronize writes to the dictionary.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.GetConversationById(System.String)">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
<param name="id"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.EndOnTimeOut">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.PauseConversations">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.FreeEnded">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.AddConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.SetActiveConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.LoadActiveConversation">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.Dispose">
|
||||
<summary>
|
||||
Ends all conversations and Closes all their Session.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Spring.Web.Conversation.WebConversationManager.RemoveConversation(Spring.Web.Conversation.IConversationState)">
|
||||
<summary>
|
||||
Remove conversation.
|
||||
</summary>
|
||||
<param name="conversation"></param>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.ActiveConversation">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.SessionFactoryName">
|
||||
<summary>
|
||||
"SessionFactory" name in the current context.
|
||||
This approach is required to support serialization.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.SessionFactory">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.EndPaused">
|
||||
<summary>
|
||||
<see cref="T:Spring.Web.Conversation.IConversationManager"/>
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Spring.Web.Conversation.WebConversationManager.ApplicationContext">
|
||||
<summary>
|
||||
Returns the current context. Supports serialization and deserialization.
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
||||
@@ -0,0 +1,354 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
public abstract class AbstractConfigurationClassPostProcessorTests
|
||||
{
|
||||
protected AbstractApplicationContext _ctx;
|
||||
|
||||
[SetUp]
|
||||
public void _SetUp()
|
||||
{
|
||||
SingletonParent.InstanceCount = 0;
|
||||
SingletonChild.InstanceCount = 0;
|
||||
PrototypeParent.InstanceCount = 0;
|
||||
PrototypeChild.InstanceCount = 0;
|
||||
CreateApplicationContext();
|
||||
}
|
||||
|
||||
|
||||
protected abstract void CreateApplicationContext();
|
||||
|
||||
|
||||
[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 = (SingletonChild)_ctx[typeof(SingletonChild).Name];
|
||||
var secondObject = (SingletonChild)_ctx[typeof(SingletonChild).Name];
|
||||
|
||||
Assert.That(SingletonChild.InstanceCount, Is.EqualTo(1));
|
||||
Assert.That(firstObject, Is.SameAs(secondObject));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Default_Singleton_Scope_With_Explicit_Prototype_Dependency()
|
||||
{
|
||||
var firstObject = (SingletonParent)_ctx[typeof(SingletonParent).Name];
|
||||
var secondObject = (SingletonParent)_ctx[typeof(SingletonParent).Name];
|
||||
|
||||
Assert.That(SingletonParent.InstanceCount, Is.EqualTo(1));
|
||||
//Assert.That(PrototypeChild.InstanceCount, Is.EqualTo(2)); // Requires scoped proxies
|
||||
Assert.That(firstObject, Is.SameAs(secondObject));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Explicit_Prototype_Scope()
|
||||
{
|
||||
var firstObject = (PrototypeChild)_ctx[typeof(PrototypeChild).Name];
|
||||
var secondObject = (PrototypeChild)_ctx[typeof(PrototypeChild).Name];
|
||||
|
||||
Assert.That(PrototypeChild.InstanceCount, Is.EqualTo(3)); // One instance used by SingletonParent
|
||||
Assert.That(firstObject, Is.Not.SameAs(secondObject));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Explicit_Prototype_Scope_With_Default_Singleton_Dependency()
|
||||
{
|
||||
var firstObject = (PrototypeParent)_ctx[typeof(PrototypeParent).Name];
|
||||
var secondObject = (PrototypeParent)_ctx[typeof(PrototypeParent).Name];
|
||||
|
||||
Assert.That(PrototypeParent.InstanceCount, Is.EqualTo(2));
|
||||
Assert.That(SingletonChild.InstanceCount, Is.EqualTo(1));
|
||||
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.Tests/Spring.Context.Attributes/ObjectDefinitions.xml", DefinitionReader = typeof(XmlObjectDefinitionReader))]
|
||||
[ImportResource("assembly://Spring.Core.Tests/Spring.Context.Attributes/ObjectDefinitionsTwo.xml")]
|
||||
public class TheImportedConfigurationClass
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual AnImportedType AnImportedType()
|
||||
{
|
||||
return new AnImportedType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
[Import(typeof(TheImportedConfigurationClass))]
|
||||
public class TheConfigurationClass
|
||||
{
|
||||
[ObjectDef(Names = "TheName")]
|
||||
public virtual SingleNamedObject NamedObject()
|
||||
{
|
||||
return new SingleNamedObject();
|
||||
}
|
||||
|
||||
[ObjectDef(DestroyMethod = "CallToDestroy", InitMethod = "CallToInit")]
|
||||
public virtual ObjectWithInitAndDestroyMethods ObjectWithInitAndDestroyMethods()
|
||||
{
|
||||
return new ObjectWithInitAndDestroyMethods();
|
||||
}
|
||||
|
||||
[ObjectDef(Names = "TheFirstAlias,TheSecondAlias")]
|
||||
public virtual ObjectWithAnAlias ObjectWithAnAlias()
|
||||
{
|
||||
return new ObjectWithAnAlias();
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
[Scope(ObjectScope.Prototype)]
|
||||
public virtual PrototypeParent PrototypeParent()
|
||||
{
|
||||
return new PrototypeParent(SingletonChild());
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
[Scope(ObjectScope.Prototype)]
|
||||
public virtual PrototypeChild PrototypeChild()
|
||||
{
|
||||
return new PrototypeChild();
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
public virtual SingletonParent SingletonParent()
|
||||
{
|
||||
return new SingletonParent(PrototypeChild());
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
public virtual SingletonChild SingletonChild()
|
||||
{
|
||||
return new SingletonChild();
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
[Lazy]
|
||||
public virtual ImplicitLazyInitObject ImplicitLazyInitObject()
|
||||
{
|
||||
return new ImplicitLazyInitObject();
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
[Lazy(true)]
|
||||
public virtual ExplicitLazyInitObject ExplicitLazyInitObject()
|
||||
{
|
||||
return new ExplicitLazyInitObject();
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
[Lazy(false)]
|
||||
public virtual ExplicitNonLazyInitObject ExplicitNonLazyInitObject()
|
||||
{
|
||||
return new ExplicitNonLazyInitObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
[Configuration]
|
||||
public class DerivedConfiguration : BaseConfigurationClass
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual TestObject DerivedDefinition()
|
||||
{
|
||||
return new TestObject(BaseDefinition());
|
||||
}
|
||||
}
|
||||
|
||||
public class BaseConfigurationClass
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual string BaseDefinition()
|
||||
{
|
||||
return Guid.NewGuid().ToString();
|
||||
}
|
||||
}
|
||||
|
||||
public class TypeRegisteredInXml { }
|
||||
|
||||
public class TypeRegisteredInXmlTwo { }
|
||||
|
||||
public class AnImportedType { }
|
||||
|
||||
public class ImplicitLazyInitObject { }
|
||||
|
||||
public class ExplicitLazyInitObject { }
|
||||
|
||||
public class ExplicitNonLazyInitObject { }
|
||||
|
||||
public class ObjectWithAnAlias { }
|
||||
|
||||
public class SingleNamedObject { }
|
||||
|
||||
public class SingletonParent
|
||||
{
|
||||
public static int InstanceCount = 0;
|
||||
private PrototypeChild _child;
|
||||
|
||||
public SingletonParent(PrototypeChild child)
|
||||
{
|
||||
InstanceCount++;
|
||||
_child = child;
|
||||
}
|
||||
|
||||
public PrototypeChild Child
|
||||
{
|
||||
get
|
||||
{
|
||||
return _child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class SingletonChild
|
||||
{
|
||||
public static int InstanceCount = 0;
|
||||
|
||||
public SingletonChild()
|
||||
{
|
||||
InstanceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public class PrototypeParent
|
||||
{
|
||||
public static int InstanceCount = 0;
|
||||
private SingletonChild _child;
|
||||
|
||||
public PrototypeParent(SingletonChild child)
|
||||
{
|
||||
InstanceCount++;
|
||||
_child = child;
|
||||
}
|
||||
|
||||
public SingletonChild Child
|
||||
{
|
||||
get
|
||||
{
|
||||
return _child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class PrototypeChild
|
||||
{
|
||||
public static int InstanceCount = 0;
|
||||
|
||||
public PrototypeChild()
|
||||
{
|
||||
InstanceCount++;
|
||||
}
|
||||
}
|
||||
|
||||
public class TestObject
|
||||
{
|
||||
private readonly string _value;
|
||||
|
||||
public TestObject(string value)
|
||||
{
|
||||
_value = value;
|
||||
}
|
||||
|
||||
public string Value
|
||||
{
|
||||
get { return _value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 NUnit.Framework;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class AssemblyObjectDefinitionScannerTests
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Spring.Core;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class AssemblyTypeScannerTests
|
||||
{
|
||||
#region Setup/Teardown
|
||||
|
||||
[SetUp]
|
||||
public void _TestSetup()
|
||||
{
|
||||
_scanner = new AssemblyObjectDefinitionScanner();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[Test]
|
||||
public void AssemblyHavingType_T_Adds_Assembly()
|
||||
{
|
||||
_scanner.AssemblyHavingType<IOrdered>();
|
||||
Assert.That(TypeSources.Any(t => t.Contains(typeof (IOrdered))));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeType_T_Adds_Type()
|
||||
{
|
||||
_scanner.IncludeType<IOrdered>();
|
||||
_scanner.IncludeType<IPriorityOrdered>();
|
||||
|
||||
IncludePredicates.Any(p => p(typeof (IOrdered)));
|
||||
IncludePredicates.Any(p => p(typeof (IPriorityOrdered)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithExcludeFilter_Excludes_Type()
|
||||
{
|
||||
//var scanner1 = new AssemblyObjectDefinitionScanner();
|
||||
|
||||
_scanner.IncludeType<TheConfigurationClass>();
|
||||
_scanner.IncludeType<TheImportedConfigurationClass>();
|
||||
_scanner.WithExcludeFilter(t => t.Name.StartsWith("TheImported"));
|
||||
|
||||
IEnumerable<Type> types = _scanner.Scan();
|
||||
|
||||
//Assert.That(types.Any(t => t.Name == "TheConfigurationClass"));
|
||||
//Assert.False(types.Any(t => t.Name == "TheImportedConfigurationClass"));
|
||||
|
||||
Assert.That(types, Contains.Item((typeof (TheConfigurationClass))));
|
||||
Assert.False(types.Contains(typeof (TheImportedConfigurationClass)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithIncludeFilter_Includes_Types()
|
||||
{
|
||||
_scanner.WithIncludeFilter(t => t.Name.Contains("ConfigurationClass"));
|
||||
|
||||
IEnumerable<Type> types = _scanner.Scan();
|
||||
|
||||
Assert.That(types, Contains.Item((typeof (TheConfigurationClass))));
|
||||
Assert.That(types, Contains.Item((typeof (TheImportedConfigurationClass))));
|
||||
Assert.That(types.Count(),Is.EqualTo(2));
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
private class Scanner : AssemblyTypeScanner
|
||||
{
|
||||
protected override bool IsCompoundPredicateSatisfiedBy(Type type)
|
||||
{
|
||||
return IsIncludedType(type) && !IsExcludedType(type);
|
||||
}
|
||||
}
|
||||
|
||||
private AssemblyObjectDefinitionScanner _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, "TypeExclusionPredicates"));
|
||||
}
|
||||
}
|
||||
|
||||
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, "TypeInclusionPredicates"));
|
||||
}
|
||||
}
|
||||
|
||||
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"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Context.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class CodeConfigApplicationContextTests : AbstractConfigurationClassPostProcessorTests
|
||||
{
|
||||
|
||||
protected override void CreateApplicationContext()
|
||||
{
|
||||
GenericApplicationContext ctx = new GenericApplicationContext();
|
||||
|
||||
ctx.ScanAllAssemblies();
|
||||
|
||||
ctx.Refresh();
|
||||
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ConfigurationClassObjectDefinitionReaderTests
|
||||
{
|
||||
[Test]
|
||||
public void ShouldNotTryToResolveAbstractDefinitionsToType()
|
||||
{
|
||||
GenericObjectDefinition definition = new GenericObjectDefinition();
|
||||
definition.ObjectTypeName = "~/Default.aspx";
|
||||
definition.IsAbstract = true;
|
||||
Assert.That(ConfigurationClassObjectDefinitionReader.CheckConfigurationClassCandidate(definition), Is.False);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ConfigurationClassParserTests
|
||||
{
|
||||
private ConfigurationClassParser _parser;
|
||||
|
||||
[SetUp]
|
||||
public void SetUp()
|
||||
{
|
||||
_parser = new ConfigurationClassParser(new FailFastProblemReporter());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ShouldBeAbleToRegisterSameNamedConfigurationClassesFromDifferentNamespaces()
|
||||
{
|
||||
_parser.Parse(typeof(ConfigurationNameSpace1.SpringConfiguration), "1");
|
||||
_parser.Parse(typeof(ConfigurationNameSpace2.SpringConfiguration), "2");
|
||||
|
||||
Assert.That(_parser.ConfigurationClasses.Count, Is.EqualTo(2), "Did not find two configuration classes");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ConfigurationNameSpace1
|
||||
{
|
||||
[Configuration]
|
||||
public class SpringConfiguration
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual string ConfigurationNameSpaceObjectA()
|
||||
{
|
||||
return "A";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace ConfigurationNameSpace2
|
||||
{
|
||||
[Configuration]
|
||||
public class SpringConfiguration
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual string ConfigurationNameSpaceObjectB()
|
||||
{
|
||||
return "B";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ConfigurationClassPostProcessorTests : AbstractConfigurationClassPostProcessorTests
|
||||
{
|
||||
|
||||
protected override void CreateApplicationContext()
|
||||
{
|
||||
GenericApplicationContext 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();
|
||||
|
||||
_ctx = ctx;
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void ShouldAllowConfigurationClassInheritance()
|
||||
{
|
||||
var factory = new DefaultListableObjectFactory();
|
||||
factory.RegisterObjectDefinition("DerivedConfiguration", new GenericObjectDefinition
|
||||
{
|
||||
ObjectType = typeof(DerivedConfiguration)
|
||||
});
|
||||
|
||||
var processor = new ConfigurationClassPostProcessor();
|
||||
|
||||
processor.PostProcessObjectFactory(factory);
|
||||
|
||||
// we should get singleton instances only
|
||||
TestObject testObject = (TestObject) factory.GetObject("DerivedDefinition");
|
||||
string singletonParent = (string) factory.GetObject("BaseDefinition");
|
||||
|
||||
|
||||
Assert.That(testObject.Value, Is.SameAs(singletonParent));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,207 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class FailAssemblyObjectDefinitionScannerTests
|
||||
{
|
||||
#region Setup/Teardown
|
||||
|
||||
[SetUp]
|
||||
public void _SetUp()
|
||||
{
|
||||
_scanner = new AssemblyObjectDefinitionScanner();
|
||||
_context = new CodeConfigApplicationContext();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private void ScanForAndRegisterSingleType(Type type)
|
||||
{
|
||||
_scanner.WithIncludeFilter(t => t.Name == type.Name);
|
||||
_scanner.ScanAndRegisterTypes(_context.DefaultListableObjectFactory);
|
||||
AttributeConfigUtils.RegisterAttributeConfigProcessors((IObjectDefinitionRegistry)_context.ObjectFactory);
|
||||
}
|
||||
|
||||
private CodeConfigApplicationContext _context;
|
||||
private AssemblyObjectDefinitionScanner _scanner;
|
||||
|
||||
[Test]
|
||||
public void Can_Ignore_Abstract_Configuration_Types()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(ConfigurationClassThatIsAbstract));
|
||||
Assert.That(_context.GetObjectNamesForType(typeof(ConfigurationClassThatIsAbstract)).Count, Is.EqualTo(0), "Abstract Type erroneously registered with the Context.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Prevent_Methods_With_Parameters()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(ConfigurationClassWithMethodHavingParameters));
|
||||
Assert.Throws<ObjectDefinitionParsingException>(_context.Refresh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Prevent_Static_Methods()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(ConfigurationClassWithStaticMethod));
|
||||
Assert.Throws<ObjectDefinitionParsingException>(_context.Refresh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Prevent_Non_Virtual_Methods()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(ConfigurationClassWithNonVirtualMethod));
|
||||
Assert.Throws<ObjectDefinitionParsingException>(_context.Refresh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Prevent_Sealed_Configuration_Types()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(ConfigurationClassThatIsSealed));
|
||||
Assert.Throws<ObjectDefinitionParsingException>(_context.Refresh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Prevent_Overloaded_Methods()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(ConfigurationClassWithOverloadedMethods));
|
||||
Assert.Throws<ObjectDefinitionParsingException>(_context.Refresh);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Prevent_Circular_ConfigurationClass_Refereces()
|
||||
{
|
||||
ScanForAndRegisterSingleType(typeof(FirstConfigurationClassWithCircularReference));
|
||||
|
||||
try
|
||||
{
|
||||
_context.Refresh();
|
||||
}
|
||||
catch (ObjectDefinitionStoreException ex)
|
||||
{
|
||||
Assert.That(ex.InnerException, Is.TypeOf(typeof(ObjectDefinitionParsingException)));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class SomeType
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
[Configuration]
|
||||
public class ConfigurationClassWithNonVirtualMethod
|
||||
{
|
||||
[ObjectDef]
|
||||
public SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
public class ConfigurationClassWithStaticMethod
|
||||
{
|
||||
[ObjectDef]
|
||||
public static SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
public class ConfigurationClassWithOverloadedMethods
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
|
||||
[ObjectDef]
|
||||
public virtual SomeType MethodThatRegistersSomeType(int i)
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
[Import(typeof(SecondConfigurationClassWithCircularReference))]
|
||||
public class FirstConfigurationClassWithCircularReference
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
[Import(typeof(FirstConfigurationClassWithCircularReference))]
|
||||
public class SecondConfigurationClassWithCircularReference
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Configuration]
|
||||
public class ConfigurationClassWithMethodHavingParameters
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual SomeType MethodThatRegistersSomeType(int i)
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[Configuration]
|
||||
public abstract class ConfigurationClassThatIsAbstract
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
public sealed class ConfigurationClassThatIsSealed
|
||||
{
|
||||
[ObjectDef]
|
||||
public SomeType MethodThatRegistersSomeType()
|
||||
{
|
||||
return new SomeType();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 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 pass *anything* ensured *not* to implement IObjectDefinitionReader
|
||||
Assert.Fail("Expected Exception of type ArgumentException not thrown!");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
//swallow the expected exception
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ObjectDefAttributeTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Accept_Single_Name()
|
||||
{
|
||||
var def = new ObjectDefAttribute();
|
||||
|
||||
def.Names = "Steve";
|
||||
|
||||
Assert.That(def.NamesToArray[0], Is.EqualTo("Steve"));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Can_Accept_Multiple_Names()
|
||||
{
|
||||
var def = new ObjectDefAttribute();
|
||||
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"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net" >
|
||||
<object id="xmlRegisteredObject" type="Spring.Context.Attributes.TypeRegisteredInXml, Spring.Core.Tests" />
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net" >
|
||||
<object id="xmlRegisteredObjectTwo" type="Spring.Context.Attributes.TypeRegisteredInXmlTwo, Spring.Core.Tests" />
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Context.Config;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ScanningConfigurationClassPostProcessorTests : AbstractConfigurationClassPostProcessorTests
|
||||
{
|
||||
protected override void CreateApplicationContext()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
_ctx = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("SimpleScanTest.xml", GetType()));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ContextNotNull()
|
||||
{
|
||||
Assert.That(_ctx, Is.Not.Null);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies=""/>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Context.Config;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Example.Scannable;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
public class SimpleScanTests
|
||||
{
|
||||
private IApplicationContext _applicationContext;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("SimpleScanTest.xml", GetType()));
|
||||
}
|
||||
|
||||
//[Test]
|
||||
public void FooService()
|
||||
{
|
||||
|
||||
IFooService fooService = GetObject<IFooService>();
|
||||
|
||||
}
|
||||
|
||||
public T GetObject<T>()
|
||||
{
|
||||
return (T)DoGetInstance(typeof(T), null);
|
||||
}
|
||||
public T GetObject<T>(string name)
|
||||
{
|
||||
return (T)DoGetInstance(typeof(T), name);
|
||||
}
|
||||
|
||||
protected object DoGetInstance(Type serviceType, string key)
|
||||
{
|
||||
if (key == null)
|
||||
{
|
||||
IEnumerator it = DoGetAllInstances(serviceType).GetEnumerator();
|
||||
if (it.MoveNext())
|
||||
{
|
||||
return it.Current;
|
||||
}
|
||||
throw new ObjectCreationException(string.Format("no services of type '{0}' defined", serviceType.FullName));
|
||||
}
|
||||
return _applicationContext.GetObject(key, serviceType);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resolves service instances by type.
|
||||
/// </summary>
|
||||
/// <param name="serviceType">Type of service requested.</param>
|
||||
/// <returns>
|
||||
/// Sequence of service instance objects matching the <paramref name="serviceType"/>.
|
||||
/// </returns>
|
||||
protected IEnumerable<object> DoGetAllInstances(Type serviceType)
|
||||
{
|
||||
foreach (string objectName in _applicationContext.GetObjectNamesForType(serviceType))
|
||||
{
|
||||
yield return _applicationContext.GetObject(objectName);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#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 NUnit.Framework;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
[TestFixture]
|
||||
public class AttributeConfigObjectDefinitionParserTests
|
||||
{
|
||||
private XmlApplicationContext _applicationContext;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RegisteredComponents()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.AttributeConfigParser.xml", GetType()));
|
||||
var objectDefintionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.AUTOWIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.REQUIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.INITDESTROY_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
using NUnit.Framework;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
[TestFixture]
|
||||
public class ComponentScanObjectDefinitionParserAssemblyFilterTests
|
||||
{
|
||||
private IApplicationContext _applicationContext;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void BaseAssembliesAttributeRequired()
|
||||
{
|
||||
Assert.That(delegate { _applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.BaseAssemblyTestWithout.xml", GetType())); },
|
||||
Throws.Exception);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SingleAssemblyNameProvided()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.BaseAssemblyTestSingle.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.GreaterThan(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void MultipleAssemblyNameProvided()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.BaseAssemblyTestMultiple.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.GreaterThan(0));
|
||||
}
|
||||
[Test]
|
||||
public void NegativeAssemblyNameProvided()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.BaseAssemblyTestNegative.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
#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 NUnit.Framework;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Stereotype;
|
||||
using Spring.Objects.Factory.Attributes;
|
||||
using ComponentScan.Qualifier;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
[TestFixture]
|
||||
public class ComponentScanObjectDefinitionParserTests
|
||||
{
|
||||
private XmlApplicationContext _applicationContext;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ScanComponentsAndAddToContext()
|
||||
{
|
||||
var prefix = "ComponentScan.ScanComponentsAndAddToContext.";
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan1.xml", GetType()));
|
||||
var objectDefinitionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefinitionNames.Count, Is.EqualTo(5+4));
|
||||
Assert.That(_applicationContext.GetObject(prefix + "ComponentImpl"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject(prefix + "ServiceImpl"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject(prefix + "RepositoryImpl"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject(prefix + "ControllerImpl"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject(prefix + "ConfigurationImpl"), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComponentsUseSpecifiedName()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan2.xml", GetType()));
|
||||
var objectDefinitionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefinitionNames.Count, Is.EqualTo(5 + 4));
|
||||
Assert.That(_applicationContext.GetObject("Component"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("Service"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("Repository"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("Controller"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("Configuration"), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UseSpecifiedObjectNameGenerator()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan3.xml", GetType()));
|
||||
var objectDefinitionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefinitionNames.Contains("prototype"), Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void UseWrongObjectNameGeneratorTypeString()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan31.xml", GetType()));
|
||||
var objectDefinitionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefinitionNames.Contains("prototype"), Is.False);
|
||||
Assert.That(objectDefinitionNames.Contains("ComponentScan.NameGenerator.Prototype"), Is.True);
|
||||
}
|
||||
[Test]
|
||||
public void ComponentsLazyLoaded()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan4.xml", GetType()));
|
||||
var objectDefinition = _applicationContext.ObjectFactory.GetObjectDefinition("LazyInit");
|
||||
|
||||
Assert.That(objectDefinition.IsLazyInit, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComponentsInDifferentScope()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan4.xml", GetType()));
|
||||
var singletonDef = _applicationContext.ObjectFactory.GetObjectDefinition("Singleton");
|
||||
var prototypeDef = _applicationContext.ObjectFactory.GetObjectDefinition("Prototype");
|
||||
|
||||
Assert.That(singletonDef.IsSingleton, Is.True);
|
||||
Assert.That(singletonDef.Scope, Is.EqualTo(ObjectScope.Singleton.ToString().ToLower()));
|
||||
|
||||
Assert.That(prototypeDef.IsSingleton, Is.False);
|
||||
Assert.That(prototypeDef.Scope, Is.EqualTo(ObjectScope.Prototype.ToString().ToLower()));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComponentsUseDefaults()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan5.xml", GetType()));
|
||||
var prototypeDef = _applicationContext.ObjectFactory.GetObjectDefinition("Prototype");
|
||||
|
||||
Assert.That(prototypeDef.IsLazyInit, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComponentWithQualifier()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan6.xml", GetType()));
|
||||
var objectDef = _applicationContext.ObjectFactory.GetObjectDefinition("Prototype") as ScannedGenericObjectDefinition;
|
||||
|
||||
Assert.That(objectDef.HasQualifier(typeof(QualifierAttribute).Name), Is.True);
|
||||
|
||||
var attr = objectDef.GetQualifier(typeof (QualifierAttribute).Name).GetAttribute(AutowireCandidateQualifier.VALUE_KEY);
|
||||
Assert.That(attr, Is.EqualTo("action"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ComponentWithQualifierAttributes()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScan6.xml", GetType()));
|
||||
var objectDef = _applicationContext.ObjectFactory.GetObjectDefinition("Attribute") as ScannedGenericObjectDefinition;
|
||||
var qualifier = objectDef.GetQualifier(typeof (MyQualifier).Name);
|
||||
|
||||
Assert.That(qualifier, Is.Not.Null);
|
||||
|
||||
var attr = qualifier.GetMetadataAttribute("Foo");
|
||||
Assert.That(attr, Is.Not.Null);
|
||||
Assert.That(attr.Value, Is.EqualTo("Funny"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DontRegisterAttributeConfig()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScanAttributeConfigFalse.xml", GetType()));
|
||||
var objectDefintionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefintionNames.Count, Is.EqualTo(0));
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.False);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.AUTOWIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.False);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.REQUIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.False);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.INITDESTROY_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void RegisterAttributeConfig()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.ComponentScanAttributeConfigTrue.xml", GetType()));
|
||||
var objectDefintionNames = _applicationContext.ObjectFactory.GetObjectDefinitionNames();
|
||||
|
||||
Assert.That(objectDefintionNames.Count, Is.EqualTo(4));
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.AUTOWIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.REQUIRED_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
Assert.That(objectDefintionNames.Contains(AttributeConfigUtils.INITDESTROY_ATTRIBUTE_PROCESSOR_OBJECT_NAME), Is.True);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace ComponentScan.ScanComponentsAndAddToContext
|
||||
{
|
||||
public interface IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component]
|
||||
public class ComponentImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Service]
|
||||
public class ServiceImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Repository]
|
||||
public class RepositoryImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Controller]
|
||||
public class ControllerImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
public class ConfigurationImpl : IFoo
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace ComponentScan.ComponentsUseSpecifiedName
|
||||
{
|
||||
public interface IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component("Component")]
|
||||
public class ComponentImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Service("Service")]
|
||||
public class ServiceImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Repository("Repository")]
|
||||
public class RepositoryImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Controller("Controller")]
|
||||
public class ControllerImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Configuration("Configuration")]
|
||||
public class ConfigurationImpl : IFoo
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace ComponentScan.ComponentsAttributeLoad
|
||||
{
|
||||
public interface IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component("LazyInit")]
|
||||
[Lazy]
|
||||
public class LazyImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component("Singleton")]
|
||||
[Scope(ObjectScope.Singleton)]
|
||||
public class SingletonImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component("Prototype")]
|
||||
[Scope(ObjectScope.Prototype)]
|
||||
public class PrototypeImpl : IFoo
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace ComponentScan.ComponentsUseDefaults
|
||||
{
|
||||
public interface IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component("Prototype")]
|
||||
public class PrototypeImpl : IFoo
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
namespace ComponentScan.Qualifier
|
||||
{
|
||||
public interface IFoo
|
||||
{
|
||||
}
|
||||
|
||||
public class MyQualifier : QualifierAttribute
|
||||
{
|
||||
public string Foo { get; set; }
|
||||
}
|
||||
|
||||
[Component("Prototype")]
|
||||
[Qualifier("action")]
|
||||
public class PrototypeImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
[Component("Attribute")]
|
||||
[MyQualifier(Foo="Funny")]
|
||||
public class QualifierAttributeImpl : IFoo
|
||||
{
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace ComponentScan.NameGenerator
|
||||
{
|
||||
public interface IFoo
|
||||
{
|
||||
}
|
||||
|
||||
public class MyGenerator : IObjectNameGenerator
|
||||
{
|
||||
public string GenerateObjectName(IObjectDefinition definition, IObjectDefinitionRegistry registry)
|
||||
{
|
||||
string typeName = definition.ObjectType.Name;
|
||||
return typeName.ToLower();
|
||||
}
|
||||
}
|
||||
|
||||
[Component]
|
||||
public class Prototype : IFoo
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
#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;
|
||||
using NUnit.Framework;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Context.Attributes.TypeFilters;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Stereotype;
|
||||
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
[TestFixture]
|
||||
public class ComponentScanObjectDefinitionParserTypeFilterTests
|
||||
{
|
||||
private IApplicationContext _applicationContext;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeRegExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestRegExInclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(6));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType1"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeExcludeType"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeMultipleRegExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestRegExInclude2.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(8));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType1"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType2"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeExcludeType"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExcludeRegExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestRegExExclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(8));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType1"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeExcludeType"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeAttributeExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestAttributeInclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(6));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType2"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeExcludeType"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExcludeAttributeExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestAttributeExclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(8));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType2"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("SomeExcludeType"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeIncludeType1"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeAssignableExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestAssignableInclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(8));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType1"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType2"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeExcludeType"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExcludeAssignableExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestAssignableExclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(8));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType1"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("SomeExcludeType"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeIncludeType2"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeCustomExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestCustomInclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(6));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType1"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeIncludeType2"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ExcludeCustomExpressionFilter()
|
||||
{
|
||||
_applicationContext = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("ConfigFiles.TypeScannerTestCustomExclude.xml", GetType()));
|
||||
|
||||
Assert.That(_applicationContext.GetObjectDefinitionNames().Count, Is.EqualTo(8));
|
||||
Assert.That(_applicationContext.GetObject("SomeIncludeType2"), Is.Not.Null);
|
||||
Assert.That(_applicationContext.GetObject("SomeExcludeType"), Is.Not.Null);
|
||||
Assert.That(delegate { _applicationContext.GetObject("SomeIncludeType1"); }, Throws.Exception.TypeOf<NoSuchObjectDefinitionException>());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace XmlAssemblyTypeScanner.Test.Include1
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class DoNotIncludeAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
[DoNotInclude]
|
||||
public class SomeIncludeConfiguration1 : IFunny
|
||||
{
|
||||
[ObjectDef]
|
||||
public virtual SomeIncludeType1 SomeIncludeType1()
|
||||
{
|
||||
return new SomeIncludeType1();
|
||||
}
|
||||
}
|
||||
|
||||
public class SomeIncludeType1
|
||||
{
|
||||
}
|
||||
|
||||
public interface IFunny
|
||||
{}
|
||||
|
||||
|
||||
public class TestFilter : ITypeFilter
|
||||
{
|
||||
public bool Match(Type type)
|
||||
{
|
||||
return type.Name.Equals("SomeIncludeConfiguration1");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace XmlAssemblyTypeScanner.Test.Include2
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class DoIncludeAttribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
[DoInclude]
|
||||
public class SomeIncludeConfiguration2 : FunnyAbstract
|
||||
{
|
||||
public override void Test() { }
|
||||
|
||||
[ObjectDef]
|
||||
public virtual SomeIncludeType2 SomeIncludeType2()
|
||||
{
|
||||
return new SomeIncludeType2();
|
||||
}
|
||||
}
|
||||
|
||||
public class SomeIncludeType2
|
||||
{
|
||||
}
|
||||
|
||||
public abstract class FunnyAbstract
|
||||
{
|
||||
public abstract void Test();
|
||||
}
|
||||
}
|
||||
|
||||
namespace XmlAssemblyTypeScanner.Test.Include
|
||||
{
|
||||
[Configuration]
|
||||
public class SomeExcludeConfiguration3
|
||||
{
|
||||
|
||||
[ObjectDef]
|
||||
public virtual SomeExcludeType SomeExcludeType()
|
||||
{
|
||||
return new SomeExcludeType();
|
||||
}
|
||||
}
|
||||
|
||||
public class SomeExcludeType
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:attribute-config />
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests,AnotherAssembly"/>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="DoesNotExists"/>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests"/>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan />
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.ScanComponentsAndAddToContext.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.ComponentsUseSpecifiedName.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests"
|
||||
name-generator="ComponentScan.NameGenerator.MyGenerator, Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.NameGenerator.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests"
|
||||
name-generator="ComponentScan.NameGenerator.NotExistsGenerator, Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.NameGenerator.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.ComponentsAttributeLoad.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context"
|
||||
default-lazy-init="true">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.ComponentsUseDefaults.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression="ComponentScan.Qualifier.*"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Configuration.Invalid" attribute-config="false" />
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Configuration.Invalid" />
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression=".*Test.*"/>
|
||||
<context:exclude-filter type="assignable" expression="XmlAssemblyTypeScanner.Test.Include2.FunnyAbstract, Spring.Core.Tests"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<!-- to test type load exception -->
|
||||
<context:include-filter type="assignable" expression="XmlAssemblyTypeScanner.Test.Include1.NotValid, Spring.Core.Tests"/>
|
||||
|
||||
<context:include-filter type="assignable" expression="XmlAssemblyTypeScanner.Test.Include1.IFunny, Spring.Core.Tests"/>
|
||||
<context:include-filter type="assignable" expression="XmlAssemblyTypeScanner.Test.Include2.FunnyAbstract, Spring.Core.Tests"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression=".*Test.*"/>
|
||||
<context:exclude-filter type="attribute" expression="XmlAssemblyTypeScanner.Test.Include1.DoNotIncludeAttribute, Spring.Core.Tests"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<!-- to test type load exception -->
|
||||
<context:include-filter type="attribute" expression="Spring.Stereotype.ServiceAttribute, notvalid"/>
|
||||
|
||||
<context:include-filter type="attribute" expression="XmlAssemblyTypeScanner.Test.Include2.DoIncludeAttribute, Spring.Core.Tests"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression=".*Test.*"/>
|
||||
<context:exclude-filter type="custom" expression="XmlAssemblyTypeScanner.Test.Include1.TestFilter, Spring.Core.Tests"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<!-- to test type load exception -->
|
||||
<context:include-filter type="custom" expression="XmlAssemblyTypeScanner.Test.Include1.NotValid, Spring.Core.Tests"/>
|
||||
|
||||
<context:include-filter type="custom" expression="XmlAssemblyTypeScanner.Test.Include1.TestFilter, Spring.Core.Tests"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression=".*Test.*"/>
|
||||
<context:exclude-filter type="regex" expression=".*Test.*Exclude"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression=".*Test.*Include1"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net"
|
||||
xmlns:context="http://www.springframework.net/context">
|
||||
|
||||
<context:component-scan base-assemblies="Spring.Core.Tests">
|
||||
<context:include-filter type="regex" expression=".*Test.*Include1"/>
|
||||
<context:include-filter type="regex" expression=".*Test.*Include2"/>
|
||||
</context:component-scan>
|
||||
|
||||
</objects>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 NUnit.Framework;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
[TestFixture]
|
||||
public class ContextNamespaceParserTests
|
||||
{
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
NamespaceParserRegistry.RegisterParser(typeof(ContextNamespaceParser));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Registered()
|
||||
{
|
||||
Assert.IsNotNull(NamespaceParserRegistry.GetParser("http://www.springframework.net/context"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2010-2011 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.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using Spring.Context.Attributes;
|
||||
|
||||
namespace Spring.Context.Support
|
||||
{
|
||||
[TestFixture]
|
||||
public class CodeConfigApplicationContextTests
|
||||
{
|
||||
private CodeConfigApplicationContext _context;
|
||||
|
||||
[SetUp]
|
||||
public void _TestSetup()
|
||||
{
|
||||
_context = new CodeConfigApplicationContext();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Assembly_Based_On_Assembly_Metadata()
|
||||
{
|
||||
_context.ScanWithAssemblyFilter(a => a.GetName().Name.StartsWith("Spring.Core."));
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context, 45);
|
||||
}
|
||||
|
||||
[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.ScanWithAssemblyFilter(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(Spring.Core.IOrdered).Name)));
|
||||
_context.Refresh();
|
||||
|
||||
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Assembly_Containing_Specific_Type()
|
||||
{
|
||||
_context.ScanWithAssemblyFilter(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context, 45);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Specific_Type()
|
||||
{
|
||||
_context.ScanWithTypeFilter(type => type.FullName.Contains(typeof(TheImportedConfigurationClass).Name));
|
||||
_context.Refresh();
|
||||
|
||||
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(8));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Specific_Types_With_Compound_Predicate()
|
||||
{
|
||||
_context.ScanWithTypeFilter(type => type.FullName.Contains(typeof(TheImportedConfigurationClass).Name) || type.FullName.Contains(typeof(TheConfigurationClass).Name));
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context, 19);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Specific_Types_With_Multiple_Include_Filters()
|
||||
{
|
||||
var scanner = new AssemblyObjectDefinitionScanner();
|
||||
scanner.WithIncludeFilter(type => type.FullName.Contains(typeof(TheImportedConfigurationClass).Name));
|
||||
scanner.WithIncludeFilter(type => type.FullName.Contains(typeof(TheConfigurationClass).Name));
|
||||
|
||||
_context.Scan(scanner);
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context, 19);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Scanner()
|
||||
{
|
||||
AssemblyObjectDefinitionScanner scanner = new AssemblyObjectDefinitionScanner();
|
||||
scanner.AssemblyHavingType<TheConfigurationClass>();
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Perform_Scan_With_No_Filtering()
|
||||
{
|
||||
_context.ScanAllAssemblies();
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context, 45);
|
||||
}
|
||||
|
||||
private void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext context, int expectedDefinitionCount)
|
||||
{
|
||||
// only check names that are not part of configuration namespace test
|
||||
List<string> names = new List<string>(context.DefaultListableObjectFactory.GetObjectDefinitionNames());
|
||||
names.RemoveAll(x => x.StartsWith("ConfigurationNameSpace"));
|
||||
|
||||
|
||||
if (names.Count != expectedDefinitionCount)
|
||||
{
|
||||
Console.WriteLine("Actual types registered with the container:");
|
||||
foreach (var name in names)
|
||||
{
|
||||
Console.WriteLine(name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Assert.That(names.Count, Is.EqualTo(expectedDefinitionCount));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MarkerTypeForScannerToFind
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 Spring.Stereotype;
|
||||
|
||||
namespace Spring.Example.Scannable
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
[Service]
|
||||
public class FooService : IFooService
|
||||
{
|
||||
private string foo;
|
||||
|
||||
private bool initCalled;
|
||||
|
||||
|
||||
|
||||
public string Foo
|
||||
{
|
||||
get { return foo; }
|
||||
set { foo = value; }
|
||||
}
|
||||
|
||||
public bool InitCalled
|
||||
{
|
||||
get { return initCalled; }
|
||||
set { initCalled = value; }
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
32
test/Spring/Spring.Core.Tests/Example/Scannable/IFooDao.cs
Normal file
32
test/Spring/Spring.Core.Tests/Example/Scannable/IFooDao.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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
|
||||
|
||||
namespace Spring.Example.Scannable
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
public interface IFooDao
|
||||
{
|
||||
string FindFoo(string id);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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
|
||||
|
||||
namespace Spring.Example.Scannable
|
||||
{
|
||||
/// <summary>
|
||||
/// Simple service for testing of component scanning
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
public interface IFooService
|
||||
{
|
||||
string Foo { get; set; }
|
||||
|
||||
bool InitCalled { get; set; }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2010-2011 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 Spring.Stereotype;
|
||||
|
||||
namespace Spring.Example.Scannable
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
[Repository]
|
||||
public class StubFooDao : IFooDao
|
||||
{
|
||||
public string FindFoo(string id)
|
||||
{
|
||||
return "bar";
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -152,9 +152,25 @@
|
||||
<Compile Include="Context\ApplicationEventArgsTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Context\Attributes\AbstractConfigurationClassPostProcessorTests.cs" />
|
||||
<Compile Include="Context\Attributes\AssemblyObjectDefinitionScannerTests.cs" />
|
||||
<Compile Include="Context\Attributes\AssemblyTypeScannerTests.cs" />
|
||||
<Compile Include="Context\Attributes\CodeConfigApplicationContextTests.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassObjectDefinitionReaderTests.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassParserTests.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassPostProcessorTests.cs" />
|
||||
<Compile Include="Context\Attributes\ImportResourceAttributeTests.cs" />
|
||||
<Compile Include="Context\Attributes\ObjectDefAttributeTests.cs" />
|
||||
<Compile Include="Context\Attributes\ScanningConfigurationClassPostProcessorTests.cs" />
|
||||
<Compile Include="Context\Attributes\SimpleScanTests.cs" />
|
||||
<Compile Include="Context\CommonTypes.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Context\Config\AttributeConfigObjectDefinitionParserTests.cs" />
|
||||
<Compile Include="Context\Config\ComponentScanObjectDefinitionParserAssemblyFilterTests.cs" />
|
||||
<Compile Include="Context\Config\ComponentScanObjectDefinitionParserTests.cs" />
|
||||
<Compile Include="Context\Config\ComponentScanObjectDefinitionParserTypeFilterTests.cs" />
|
||||
<Compile Include="Context\Config\ContextNamespaceParserTests.cs" />
|
||||
<Compile Include="Context\ContextExceptionTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -183,6 +199,7 @@
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Context\Support\Assembler.cs" />
|
||||
<Compile Include="Context\Support\CodeConfigApplicationContextTests.cs" />
|
||||
<Compile Include="Context\Support\ContextLocatorHandlerTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
@@ -281,6 +298,10 @@
|
||||
<Compile Include="CompilerOptionsTests.cs">
|
||||
<SubType>Code</SubType>
|
||||
</Compile>
|
||||
<Compile Include="Example\Scannable\FooService.cs" />
|
||||
<Compile Include="Example\Scannable\IFooDao.cs" />
|
||||
<Compile Include="Example\Scannable\IFooService.cs" />
|
||||
<Compile Include="Example\Scannable\StubFooDao.cs" />
|
||||
<Compile Include="ExceptionsTest.cs" />
|
||||
<Compile Include="Expressions\ConstructorNodeTests.cs" />
|
||||
<Compile Include="Expressions\ExpressionEvaluatorTests.cs">
|
||||
@@ -804,6 +825,32 @@
|
||||
<EmbeddedResource Include="Context\Support\innerObjectsWithPostProcessor.xml" />
|
||||
<EmbeddedResource Include="Core\IO\ConfigSectionResourceTests_config1.xml" />
|
||||
<EmbeddedResource Include="Context\Support\XmlApplicationContextTests-SPRNET1231.xml" />
|
||||
<EmbeddedResource Include="Context\Attributes\ObjectDefinitions.xml" />
|
||||
<EmbeddedResource Include="Context\Attributes\ObjectDefinitionsTwo.xml" />
|
||||
<EmbeddedResource Include="Context\Attributes\SimpleScanTest.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\AttributeConfigParser.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\BaseAssemblyTestMultiple.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\BaseAssemblyTestNegative.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\BaseAssemblyTestSingle.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\BaseAssemblyTestWithout.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan1.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan2.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan3.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan31.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan4.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan5.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScan6.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScanAttributeConfigFalse.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\ComponentScanAttributeConfigTrue.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestAssignableExclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestAssignableInclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestAttributeExclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestAttributeInclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestCustomExclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestCustomInclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestRegExExclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestRegExInclude.xml" />
|
||||
<EmbeddedResource Include="Context\Config\ConfigFiles\TypeScannerTestRegExInclude2.xml" />
|
||||
<Content Include="Data\PathMatcher\EmptyPattern.test" />
|
||||
<Content Include="Data\PathMatcher\Examples.test" />
|
||||
<Content Include="Data\PathMatcher\InBetween.test" />
|
||||
|
||||
Reference in New Issue
Block a user