removal of Spring.Core.Configuration project and related tests in prep for merge back into trunk
This commit is contained in:
@@ -74,10 +74,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Web.Mvc.2010", "src\
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Web.Mvc.Tests.2010", "test\Spring\Spring.Web.Mvc.Tests\Spring.Web.Mvc.Tests.2010.csproj", "{D4032434-D9A8-437B-95E8-9D4DE0AD9932}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core.Configuration.2010", "src\Spring\Spring.Core.Configuration\Spring.Core.Configuration.2010.csproj", "{7B65D538-E863-4F57-8DDC-2C38E4150045}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Spring.Core.Configuration.Tests.2010", "test\Spring\Spring.Core.Configuration.Tests\Spring.Core.Configuration.Tests.2010.csproj", "{4F1A206C-09A8-43FF-B791-FE956E99A120}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|.NET = Debug|.NET
|
||||
@@ -438,26 +434,6 @@ Global
|
||||
{D4032434-D9A8-437B-95E8-9D4DE0AD9932}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D4032434-D9A8-437B-95E8-9D4DE0AD9932}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{D4032434-D9A8-437B-95E8-9D4DE0AD9932}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|.NET.ActiveCfg = Debug|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{7B65D538-E863-4F57-8DDC-2C38E4150045}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|.NET.ActiveCfg = Debug|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|.NET.ActiveCfg = Release|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
|
||||
{4F1A206C-09A8-43FF-B791-FE956E99A120}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright <20> 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using AopAlliance.Intercept;
|
||||
using Common.Logging;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Context.Attributes;
|
||||
|
||||
namespace Spring.Context.Advice
|
||||
{
|
||||
/// <summary>
|
||||
/// Intercepts calls to methods within the configuration object
|
||||
/// </summary>
|
||||
/// <author>Mark Pollack</author>
|
||||
/// <author>Erich Eichinger</author>
|
||||
public class SpringObjectMethodInterceptor : IMethodInterceptor
|
||||
{
|
||||
#region Logging Definition
|
||||
|
||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(SpringObjectMethodInterceptor));
|
||||
|
||||
#endregion
|
||||
|
||||
private readonly IConfigurableListableObjectFactory _configurableListableObjectFactory;
|
||||
|
||||
|
||||
public SpringObjectMethodInterceptor(IConfigurableListableObjectFactory configurableListableObjectFactory)
|
||||
{
|
||||
_configurableListableObjectFactory = configurableListableObjectFactory;
|
||||
|
||||
}
|
||||
|
||||
#region IMethodInterceptor Members
|
||||
|
||||
public object Invoke(IMethodInvocation invocation)
|
||||
{
|
||||
MethodInfo m = invocation.Method;
|
||||
if (m.Name.StartsWith("set_") || m.Name.StartsWith("get_"))
|
||||
return invocation.Proceed();
|
||||
|
||||
string name = m.Name;
|
||||
|
||||
object[] attribs = m.GetCustomAttributes(typeof(DefinitionAttribute), true);
|
||||
if (attribs.Length > 0)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
if (IsCurrentlyInCreation(name))
|
||||
{
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug(name + " currently in creation, created one.");
|
||||
}
|
||||
return invocation.Proceed();
|
||||
}
|
||||
if (LOG.IsDebugEnabled)
|
||||
{
|
||||
LOG.Debug(name + " not in creation, asked the application context for one");
|
||||
}
|
||||
|
||||
return _configurableListableObjectFactory.GetObject(name);
|
||||
}
|
||||
|
||||
private bool IsCurrentlyInCreation(string name)
|
||||
{
|
||||
return _configurableListableObjectFactory.IsCurrentlyInCreation(name);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,258 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.IO;
|
||||
using Common.Logging;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
public interface IAssemblyTypeScanner
|
||||
{
|
||||
IAssemblyTypeScanner AssemblyHavingType<T>();
|
||||
IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate);
|
||||
|
||||
IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate);
|
||||
IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate);
|
||||
|
||||
IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource);
|
||||
IAssemblyTypeScanner IncludeType<T>();
|
||||
IAssemblyTypeScanner ExcludeType<T>();
|
||||
|
||||
IEnumerable<Type> Scan();
|
||||
}
|
||||
|
||||
public abstract class AssemblyTypeScanner : IAssemblyTypeScanner
|
||||
{
|
||||
protected readonly List<Predicate<Assembly>> _assemblyPredicates = new List<Predicate<Assembly>>();
|
||||
|
||||
protected readonly List<Predicate<Type>> _excludePredicates = new List<Predicate<Type>>();
|
||||
|
||||
protected string _folderScanPath;
|
||||
|
||||
protected readonly List<Predicate<Type>> _includePredicates = new List<Predicate<Type>>();
|
||||
|
||||
protected static ILog _logger = LogManager.GetLogger(typeof(AssemblyTypeScanner));
|
||||
|
||||
protected readonly List<IEnumerable<Type>> _typeSources = new List<IEnumerable<Type>>();
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AssemblyTypeScanner class.
|
||||
/// </summary>
|
||||
/// <param name="folderScanPath"></param>
|
||||
public AssemblyTypeScanner(string folderScanPath)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(folderScanPath))
|
||||
{
|
||||
_folderScanPath = folderScanPath;
|
||||
}
|
||||
else
|
||||
{
|
||||
_folderScanPath = GetCurrentBinDirectoryPath();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AssemblyTypeScanner class.
|
||||
/// </summary>
|
||||
public AssemblyTypeScanner()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner AssemblyHavingType<T>()
|
||||
{
|
||||
_typeSources.Add(new AssemblyTypeSource((typeof(T).Assembly)));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner ExcludeType<T>()
|
||||
{
|
||||
_excludePredicates.Add(t => t == typeof(T));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner IncludeType<T>()
|
||||
{
|
||||
_includePredicates.Add(t => t == typeof(T));
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner IncludeTypes(IEnumerable<Type> typeSource)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(typeSource, "typeSource");
|
||||
_typeSources.Add(typeSource);
|
||||
_includePredicates.Add(t => typeSource.Any(t1 => t1 == t));
|
||||
return this;
|
||||
}
|
||||
|
||||
public virtual IEnumerable<Type> Scan()
|
||||
{
|
||||
SetDefaultFilters();
|
||||
|
||||
IList<Type> types = new List<Type>();
|
||||
|
||||
foreach (Assembly assembly in GetAllMatchingAssemblies())
|
||||
{
|
||||
_typeSources.Add(new AssemblyTypeSource(assembly));
|
||||
}
|
||||
|
||||
foreach (var typeSource in _typeSources)
|
||||
{
|
||||
foreach (Type type in typeSource)
|
||||
{
|
||||
if (IsIncludedType(type) && !IsExcludedType(type) && FinalVetoConstraintIsSatisfiedBy(type))
|
||||
{
|
||||
types.Add(type);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return types;
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner WithAssemblyFilter(Predicate<Assembly> assemblyPredicate)
|
||||
{
|
||||
_assemblyPredicates.Add(assemblyPredicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner WithExcludeFilter(Predicate<Type> predicate)
|
||||
{
|
||||
_excludePredicates.Add(predicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
public IAssemblyTypeScanner WithIncludeFilter(Predicate<Type> predicate)
|
||||
{
|
||||
_includePredicates.Add(predicate);
|
||||
return this;
|
||||
}
|
||||
|
||||
protected virtual bool IsExcludedType(Type type)
|
||||
{
|
||||
foreach (var exclude in _excludePredicates)
|
||||
{
|
||||
if (exclude(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool IsIncludedAssembly(Assembly assembly)
|
||||
{
|
||||
foreach (var include in _assemblyPredicates)
|
||||
{
|
||||
if (include(assembly))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual bool IsIncludedType(Type type)
|
||||
{
|
||||
foreach (var include in _includePredicates)
|
||||
{
|
||||
if (include(type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
protected virtual void SetDefaultFilters()
|
||||
{
|
||||
if (_includePredicates.Count == 0)
|
||||
_includePredicates.Add(t => true);
|
||||
|
||||
if (_excludePredicates.Count == 0)
|
||||
_excludePredicates.Add(t => false);
|
||||
|
||||
if (_assemblyPredicates.Count == 0)
|
||||
_assemblyPredicates.Add(a => true);
|
||||
}
|
||||
|
||||
protected virtual bool FinalVetoConstraintIsSatisfiedBy(Type type)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
private IEnumerable<Assembly> ApplyAssemblyFiltersTo(IEnumerable<Assembly> assemblyCandidates)
|
||||
{
|
||||
IList<Assembly> matchingAssemblies = new List<Assembly>();
|
||||
foreach (Assembly assemblyCandidate in assemblyCandidates)
|
||||
if (IsIncludedAssembly(assemblyCandidate))
|
||||
matchingAssemblies.Add(assemblyCandidate);
|
||||
return matchingAssemblies;
|
||||
}
|
||||
|
||||
private IEnumerable<Assembly> GetAllAssembliesInPath(string folderPath)
|
||||
{
|
||||
IList<Assembly> assemblies = new List<Assembly>();
|
||||
IEnumerable<string> files = Directory.GetFiles(folderPath, "*.dll");
|
||||
foreach (string file in files)
|
||||
try
|
||||
{
|
||||
assemblies.Add(Assembly.LoadFrom(file));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//log and swallow everything that might go wrong here...
|
||||
if (_logger.IsDebugEnabled)
|
||||
_logger.Debug("Failed to load type while scanning Assemblies for Defintions!", ex);
|
||||
}
|
||||
return assemblies;
|
||||
}
|
||||
|
||||
private IEnumerable<Assembly> GetAllMatchingAssemblies()
|
||||
{
|
||||
IEnumerable<Assembly> assemblyCandidates = GetAllAssembliesInPath(_folderScanPath);
|
||||
return ApplyAssemblyFiltersTo(assemblyCandidates);
|
||||
}
|
||||
|
||||
private string GetCurrentBinDirectoryPath()
|
||||
{
|
||||
return Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class AssemblyObjectDefinitionScanner : AssemblyTypeScanner
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
|
||||
/// </summary>
|
||||
/// <param name="folderScanPath">The folder scan path.</param>
|
||||
public AssemblyObjectDefinitionScanner(string folderScanPath)
|
||||
: base(folderScanPath)
|
||||
{ }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the AssemblyObjectDefinitionScanner class.
|
||||
/// </summary>
|
||||
public AssemblyObjectDefinitionScanner()
|
||||
: base(null)
|
||||
{ }
|
||||
|
||||
//protected override bool RequiredConstraintIsSatisfiedBy(Type type)
|
||||
//{
|
||||
// return Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute), true) != null;
|
||||
//}
|
||||
|
||||
protected override void SetDefaultFilters()
|
||||
{
|
||||
_includePredicates.Add(t => Attribute.GetCustomAttribute(t, typeof(ConfigurationAttribute), true) != null);
|
||||
|
||||
base.SetDefaultFilters();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2008 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using System.Runtime.InteropServices;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
public class AssemblyTypeSource : IEnumerable<Type>
|
||||
{
|
||||
private readonly _Assembly assembly;
|
||||
|
||||
public AssemblyTypeSource(Assembly assembly)
|
||||
{
|
||||
AssertUtils.ArgumentNotNull(assembly, "assembly");
|
||||
this.assembly = assembly;
|
||||
}
|
||||
|
||||
public IEnumerator<Type> GetEnumerator()
|
||||
{
|
||||
foreach (var type in assembly.GetTypes())
|
||||
yield return type;
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,74 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Stereotype;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that a class declares one or more <see cref="Definition"/> methods and may be processed
|
||||
/// by the Spring container to generate object definitions and service requests for those objects
|
||||
/// at runtime.
|
||||
///
|
||||
/// <para>Configuration is meta-annotated as a {@link Component}, therefore Configuration
|
||||
/// classes are candidates for component-scanning and may also take advantage of
|
||||
/// <see cref="AutoWired"/> at the field and method but not at the constructor level.
|
||||
/// </para>
|
||||
/// <para>May be used in conjunction with the <see cref="Lazy"/> attribute to indicate that all object
|
||||
/// methods declared within this class are by default lazily initialized.
|
||||
///</para>
|
||||
/// <h3>Constraints</h3>
|
||||
/// <ul>
|
||||
/// <li>Configuration classes must be non-final</li>
|
||||
/// <li>Configuration classes must be non-local (may not be declared within a method)</li>
|
||||
/// <li>Configuration classes must have a default/no-arg constructor and may not use
|
||||
/// {@link Autowired} constructor parameters</li>
|
||||
/// </ul>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ConfigurationAttribute : ComponentAttribute
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConfigurationAttribute class.
|
||||
/// </summary>
|
||||
public ConfigurationAttribute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private string _name;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Configuration class.
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
public ConfigurationAttribute(string name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Explicitly specify the name of the Spring object definition associated
|
||||
/// with this Configuration class. If left unspecified (the common case),
|
||||
/// a object name will be automatically generated.
|
||||
///
|
||||
/// <para>The custom name applies only if the Configuration class is picked up via
|
||||
/// component scanning or supplied directly to a <see cref="AnnotationConfigApplicationContext"/>.
|
||||
/// If the Configuration class is registered as a traditional XML object definition,
|
||||
/// the name/id of the object element will take precedence.
|
||||
/// </para>
|
||||
/// <see cref="Spring.Objects.Factory.Support.DefaultObjectNameGenerator"/>
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,163 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Core.IO;
|
||||
using Spring.Collections.Generic;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
public class ConfigurationClass
|
||||
{
|
||||
private Type _configurationClassType;
|
||||
|
||||
private IDictionary<string, Type> _importedResources = new Dictionary<string, Type>();
|
||||
|
||||
private ISet<ConfigurationClassMethod> _methods = new HashedSet<ConfigurationClassMethod>();
|
||||
|
||||
private string _objectName;
|
||||
|
||||
private IResource _resource;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConfigurationClass class.
|
||||
/// </summary>
|
||||
/// <param name="objectName"></param>
|
||||
/// <param name="type"></param>
|
||||
public ConfigurationClass(string objectName, Type type)
|
||||
{
|
||||
this._objectName = objectName;
|
||||
this._configurationClassType = type;
|
||||
}
|
||||
|
||||
public Type ConfigurationClassType
|
||||
{
|
||||
get
|
||||
{
|
||||
return _configurationClassType;
|
||||
}
|
||||
}
|
||||
|
||||
public IDictionary<string, Type> ImportedResources
|
||||
{
|
||||
get
|
||||
{
|
||||
return _importedResources;
|
||||
}
|
||||
}
|
||||
|
||||
public ISet<ConfigurationClassMethod> Methods
|
||||
{
|
||||
get
|
||||
{
|
||||
return _methods;
|
||||
}
|
||||
}
|
||||
|
||||
public string ObjectName
|
||||
{
|
||||
get
|
||||
{
|
||||
return _objectName;
|
||||
}
|
||||
set
|
||||
{
|
||||
_objectName = value;
|
||||
}
|
||||
}
|
||||
|
||||
public IResource Resource
|
||||
{
|
||||
get
|
||||
{
|
||||
return _resource;
|
||||
}
|
||||
}
|
||||
|
||||
public string SimpleName
|
||||
{
|
||||
get { return ConfigurationClassType.Name; }
|
||||
}
|
||||
|
||||
public void AddImportedResource(string importedResource, Type readerClass)
|
||||
{
|
||||
_importedResources.Add(importedResource, readerClass);
|
||||
}
|
||||
|
||||
public override bool Equals(object other)
|
||||
{
|
||||
return this == other || (other is ConfigurationClass && ConfigurationClassType.Name.Equals(((ConfigurationClass)other).ConfigurationClassType.Name));
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return ConfigurationClassType.Name.GetHashCode() * 14;
|
||||
}
|
||||
|
||||
public void Validate(IProblemReporter problemReporter)
|
||||
{
|
||||
// A [Definition] method may only be overloaded through inheritance. No single
|
||||
// [Configuration] class may declare two [Definition] methods with the same name.
|
||||
char hashDelim = '#';
|
||||
Dictionary<String, int> methodNameCounts = new Dictionary<String, int>();
|
||||
foreach (ConfigurationClassMethod method in _methods)
|
||||
{
|
||||
String dClassName = method.MethodMetadata.DeclaringType.FullName;
|
||||
String methodName = method.MethodMetadata.Name;
|
||||
String fqMethodName = dClassName + hashDelim + methodName;
|
||||
if (!methodNameCounts.ContainsKey(fqMethodName))
|
||||
{
|
||||
methodNameCounts.Add(fqMethodName, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
int currentCount = methodNameCounts[fqMethodName];
|
||||
methodNameCounts.Add(fqMethodName, currentCount++);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (String methodName in methodNameCounts.Keys)
|
||||
{
|
||||
int count = methodNameCounts[methodName];
|
||||
if (count > 1)
|
||||
{
|
||||
String shortMethodName = methodName.Substring(methodName.IndexOf(hashDelim) + 1);
|
||||
problemReporter.Error(new ObjectMethodOverloadingProblem(shortMethodName, count, Resource, ConfigurationClassType));
|
||||
}
|
||||
}
|
||||
|
||||
if (Attribute.GetCustomAttribute(_configurationClassType, typeof(ConfigurationAttribute)) != null)
|
||||
{
|
||||
|
||||
if (ConfigurationClassType.IsSealed)
|
||||
{
|
||||
problemReporter.Error(new SealedConfigurationProblem(SimpleName, Resource, ConfigurationClassType));
|
||||
|
||||
}
|
||||
|
||||
foreach (ConfigurationClassMethod method in _methods)
|
||||
{
|
||||
method.Validate(problemReporter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class SealedConfigurationProblem : Problem
|
||||
{
|
||||
public SealedConfigurationProblem(string name, IResource resource, Type configurationClassType)
|
||||
: base(String.Format("[Configuration] class '{0}' may not be sealed. Remove the sealed modifier to continue.", name), new Location(resource, configurationClassType))
|
||||
{ }
|
||||
|
||||
}
|
||||
|
||||
private class ObjectMethodOverloadingProblem : Problem
|
||||
{
|
||||
public ObjectMethodOverloadingProblem(string methodName, int count, IResource resource, Type configurationClassType)
|
||||
: base(String.Format("[Configuration] class '{0}' has {1} overloaded [Definiton] methods named '{2}'. " +
|
||||
"Only one [Definition] method of a given name is allowed within each [Configuration] class.", configurationClassType.Name, count, methodName), new Location(resource, configurationClassType))
|
||||
{ }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
#region License
|
||||
|
||||
/*
|
||||
* Copyright © 2002-2010 the original author or authors.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#endregion
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Text;
|
||||
using Spring.Core.IO;
|
||||
using System.Reflection;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
/**
|
||||
* Represents a {@link Configuration} class method marked with the {@link Object} annotation.
|
||||
*
|
||||
* @author Chris Beams
|
||||
* @author Juergen Hoeller
|
||||
* @since 3.0
|
||||
* @see ConfigurationClass
|
||||
* @see ConfigurationClassParser
|
||||
* @see ConfigurationClassObjectDefinitionReader
|
||||
*/
|
||||
|
||||
public class ConfigurationClassMethod
|
||||
{
|
||||
private ConfigurationClass _configurationClass;
|
||||
|
||||
private MethodInfo _methodInfo;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConfigurationClassMethod class.
|
||||
/// </summary>
|
||||
/// <param name="methodInfo"></param>
|
||||
/// <param name="configurationClass"></param>
|
||||
public ConfigurationClassMethod(MethodInfo methodInfo, ConfigurationClass configurationClass)
|
||||
{
|
||||
_methodInfo = methodInfo;
|
||||
_configurationClass = configurationClass;
|
||||
}
|
||||
|
||||
public ConfigurationClass ConfigurationClass
|
||||
{
|
||||
get
|
||||
{
|
||||
return _configurationClass;
|
||||
}
|
||||
}
|
||||
|
||||
public MethodInfo MethodMetadata
|
||||
{
|
||||
get
|
||||
{
|
||||
return _methodInfo;
|
||||
}
|
||||
}
|
||||
|
||||
public Location ResourceLocation
|
||||
{
|
||||
get { return new Location(_configurationClass.Resource, _methodInfo); }
|
||||
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return string.Format("{0}:name={1},declaringClass={2}", this.GetType().Name, _methodInfo.Name, _methodInfo.DeclaringType.FullName);
|
||||
}
|
||||
|
||||
public void Validate(IProblemReporter problemReporter)
|
||||
{
|
||||
//TODO: shouldn't this be "if method has Definition attribute" instead of "if class has Configuration attribute" --????
|
||||
if (Attribute.GetCustomAttribute(ConfigurationClass.ConfigurationClassType, typeof(ConfigurationAttribute)) != null)
|
||||
{
|
||||
if (!MethodMetadata.IsVirtual)
|
||||
{
|
||||
problemReporter.Error(new NonVirtualMethodError(MethodMetadata.Name, ResourceLocation));
|
||||
}
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
if (MethodMetadata.IsStatic)
|
||||
{
|
||||
problemReporter.Error(new StaticMethodError(MethodMetadata.Name, ResourceLocation));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class StaticMethodError : Problem
|
||||
{
|
||||
public StaticMethodError(string methodName, Location location)
|
||||
: base(String.Format("Method '{0}' must not be static; remove the method's static modifier to continue",
|
||||
methodName), location)
|
||||
{ }
|
||||
}
|
||||
|
||||
private class NonVirtualMethodError : Problem
|
||||
{
|
||||
public NonVirtualMethodError(string methodName, Location location)
|
||||
: base(String.Format("Method '{0}' must be public virtual; change the method's modifiers to continue",
|
||||
methodName), location)
|
||||
{ }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,229 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Collections.Generic;
|
||||
using System.Reflection;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Common.Logging;
|
||||
using Spring.Objects;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
public class ConfigurationClassObjectDefinitionReader
|
||||
{
|
||||
private readonly ILog _logger = LogManager.GetLogger(typeof(ConfigurationClassObjectDefinitionReader));
|
||||
|
||||
private IProblemReporter _problemReporter;
|
||||
|
||||
private IObjectDefinitionRegistry _registry;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConfigurationClassObjectDefinitionReader class.
|
||||
/// </summary>
|
||||
/// <param name="registry"></param>
|
||||
/// <param name="problemReporter"></param>
|
||||
public ConfigurationClassObjectDefinitionReader(IObjectDefinitionRegistry registry, IProblemReporter problemReporter)
|
||||
{
|
||||
_registry = registry;
|
||||
_problemReporter = problemReporter;
|
||||
}
|
||||
|
||||
public static bool CheckConfigurationClassCandidate(Type type)
|
||||
{
|
||||
if (type != null)
|
||||
{
|
||||
return (Attribute.GetCustomAttribute(type, typeof(ConfigurationAttribute)) != null);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public void LoadObjectDefinitions(ISet<ConfigurationClass> configurationModel)
|
||||
{
|
||||
foreach (ConfigurationClass configClass in configurationModel)
|
||||
{
|
||||
LoadObjectDefinitionsForConfigurationClass(configClass);
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadObjectDefinitionForConfigurationClassIfNecessary(ConfigurationClass configClass)
|
||||
{
|
||||
if (configClass.ObjectName != null)
|
||||
{
|
||||
// a Object definition already exists for this configuration class -> nothing to do
|
||||
return;
|
||||
}
|
||||
|
||||
// no Object definition exists yet -> this must be an imported configuration class (@Import).
|
||||
GenericObjectDefinition configObjectDef = new GenericObjectDefinition();
|
||||
String className = configClass.ConfigurationClassType.Name;
|
||||
configObjectDef.ObjectType = configClass.ConfigurationClassType;
|
||||
if (CheckConfigurationClassCandidate(configClass.ConfigurationClassType))
|
||||
{
|
||||
String configObjectName = ObjectDefinitionReaderUtils.RegisterWithGeneratedName(configObjectDef, _registry);
|
||||
configClass.ObjectName = configObjectName;
|
||||
if (_logger.IsDebugEnabled)
|
||||
{
|
||||
_logger.Debug(String.Format("Registered object definition for imported [Configuration] class {0}", configObjectName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void LoadObjectDefinitionsForConfigurationClass(ConfigurationClass configClass)
|
||||
{
|
||||
LoadObjectDefinitionForConfigurationClassIfNecessary(configClass);
|
||||
|
||||
foreach (ConfigurationClassMethod method in configClass.Methods)
|
||||
{
|
||||
LoadObjectDefinitionsForModelMethod(method);
|
||||
}
|
||||
|
||||
LoadObjectDefinitionsFromImportedResources(configClass.ImportedResources);
|
||||
}
|
||||
|
||||
private void LoadObjectDefinitionsForModelMethod(ConfigurationClassMethod method)
|
||||
{
|
||||
ConfigurationClass configClass = method.ConfigurationClass;
|
||||
MethodInfo metadata = method.MethodMetadata;
|
||||
|
||||
RootObjectDefinition objDef = new ConfigurationClassObjectDefinition();
|
||||
//ObjectDef.Resource = configClass.Resource;
|
||||
//ObjectDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
|
||||
|
||||
|
||||
|
||||
objDef.FactoryObjectName = configClass.ObjectName;
|
||||
objDef.FactoryMethodName = metadata.Name;
|
||||
objDef.AutowireMode = Objects.Factory.Config.AutoWiringMode.Constructor;
|
||||
|
||||
//ObjectDef.setAttribute(RequiredAnnotationObjectPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
|
||||
|
||||
// consider name and any aliases
|
||||
//Dictionary<String, Object> ObjectAttributes = metadata.getAnnotationAttributes(Object.class.getName());
|
||||
object[] objectAttributes = metadata.GetCustomAttributes(typeof(DefinitionAttribute), true);
|
||||
List<string> names = new List<string>();
|
||||
for (int i = 0; i < objectAttributes.Length; i++)
|
||||
{
|
||||
string[] namesAndAliases = ((DefinitionAttribute)objectAttributes[i]).NamesToArray;
|
||||
|
||||
if (namesAndAliases != null)
|
||||
{
|
||||
names.Add(metadata.Name);
|
||||
}
|
||||
else
|
||||
{
|
||||
namesAndAliases = new[] { metadata.Name };
|
||||
}
|
||||
|
||||
for (int j = 0; j < namesAndAliases.Length; j++)
|
||||
{
|
||||
names.Add(namesAndAliases[j]);
|
||||
}
|
||||
}
|
||||
|
||||
string objectName = (names.Count > 0 ? names[0] : method.MethodMetadata.Name);
|
||||
for (int i = 1; i < names.Count; i++)
|
||||
{
|
||||
_registry.RegisterAlias(objectName, names[i]);
|
||||
}
|
||||
|
||||
// has this already been overridden (e.g. via XML)?
|
||||
if (_registry.ContainsObjectDefinition(objectName))
|
||||
{
|
||||
IObjectDefinition existingObjectDef = _registry.GetObjectDefinition(objectName);
|
||||
// is the existing Object definition one that was created from a configuration class?
|
||||
if (!(existingObjectDef is ConfigurationClassObjectDefinition))
|
||||
{
|
||||
// no -> then it's an external override, probably XML
|
||||
// overriding is legal, return immediately
|
||||
if (_logger.IsDebugEnabled)
|
||||
{
|
||||
_logger.Debug(String.Format("Skipping loading Object definition for {0}: a definition for object " +
|
||||
"'{1}' already exists. This is likely due to an override in XML.", method, objectName));
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(PrimaryAttribute)) != null)
|
||||
{
|
||||
//TODO: determine how to respond to this attribute's presence
|
||||
//ObjectDef.isPrimary = true;
|
||||
}
|
||||
|
||||
// is this Object to be instantiated lazily?
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(LazyAttribute)) != null)
|
||||
{
|
||||
objDef.IsLazyInit = (Attribute.GetCustomAttribute(metadata, typeof(LazyAttribute)) as LazyAttribute).LazyInitialize;
|
||||
}
|
||||
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(DependsOnAttribute)) != null)
|
||||
{
|
||||
objDef.DependsOn = (Attribute.GetCustomAttribute(metadata, typeof(DependsOnAttribute)) as DependsOnAttribute).Name;
|
||||
}
|
||||
|
||||
//Autowire autowire = (Autowire) ObjectAttributes.get("autowire");
|
||||
//if (autowire.isAutowire()) {
|
||||
// ObjectDef.setAutowireMode(autowire.value());
|
||||
//}
|
||||
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(DefinitionAttribute)) != null)
|
||||
{
|
||||
objDef.InitMethodName = (Attribute.GetCustomAttribute(metadata, typeof(DefinitionAttribute)) as DefinitionAttribute).InitMethod;
|
||||
objDef.DestroyMethodName = (Attribute.GetCustomAttribute(metadata, typeof(DefinitionAttribute)) as DefinitionAttribute).DestroyMethod;
|
||||
}
|
||||
|
||||
// consider scoping
|
||||
if (Attribute.GetCustomAttribute(metadata, typeof(ScopeAttribute)) != null)
|
||||
{
|
||||
objDef.Scope = (Attribute.GetCustomAttribute(metadata, typeof(ScopeAttribute)) as ScopeAttribute).ObjectScope.ToString();
|
||||
}
|
||||
|
||||
if (_logger.IsDebugEnabled)
|
||||
{
|
||||
_logger.Debug(String.Format("Registering Object definition for [Definition] method {0}.{1}()", configClass.ConfigurationClassType.Name, objectName));
|
||||
}
|
||||
|
||||
_registry.RegisterObjectDefinition(objectName, objDef);
|
||||
}
|
||||
|
||||
private void LoadObjectDefinitionsFromImportedResources(IDictionary<string, Type> importedResources)
|
||||
{
|
||||
IDictionary<Type, IObjectDefinitionReader> readerInstanceCache = new Dictionary<Type, IObjectDefinitionReader>();
|
||||
foreach (KeyValuePair<string, Type> entry in importedResources)
|
||||
{
|
||||
String resource = entry.Key;
|
||||
Type readerClass = entry.Value;
|
||||
|
||||
if (!readerInstanceCache.ContainsKey(readerClass))
|
||||
{
|
||||
try
|
||||
{
|
||||
IObjectDefinitionReader readerInstance =
|
||||
(IObjectDefinitionReader)Activator.CreateInstance(readerClass, _registry);
|
||||
|
||||
readerInstanceCache.Add(readerClass, readerInstance);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
throw new InvalidOperationException(String.Format("Could not instantiate IObjectDefinitionReader class {0}", readerClass.FullName));
|
||||
}
|
||||
}
|
||||
|
||||
IObjectDefinitionReader reader = readerInstanceCache[readerClass];
|
||||
|
||||
reader.LoadObjectDefinitions(resource);
|
||||
}
|
||||
}
|
||||
|
||||
private class ConfigurationClassObjectDefinition : RootObjectDefinition
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,138 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Collections.Generic;
|
||||
using Spring.Util;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
|
||||
public class ConfigurationClassParser
|
||||
{
|
||||
private ISet<ConfigurationClass> _configurationClasses = new HashedSet<ConfigurationClass>();
|
||||
|
||||
private Stack<ConfigurationClass> _importStack = new Stack<ConfigurationClass>();
|
||||
|
||||
private IProblemReporter _problemReporter;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ConfigurationClassParser class.
|
||||
/// </summary>
|
||||
/// <param name="problemReporter"></param>
|
||||
public ConfigurationClassParser(IProblemReporter problemReporter)
|
||||
{
|
||||
_problemReporter = problemReporter;
|
||||
}
|
||||
|
||||
public ISet<ConfigurationClass> ConfigurationClasses
|
||||
{
|
||||
get { return _configurationClasses; }
|
||||
}
|
||||
|
||||
//public void Parse(String className, String ObjectName)
|
||||
//{
|
||||
// ProcessConfigurationClass(new ConfigurationClass(className, ObjectName));
|
||||
//}
|
||||
|
||||
public void Parse(Type type, string objectName)
|
||||
{
|
||||
ProcessConfigurationClass(new ConfigurationClass(objectName, type));
|
||||
}
|
||||
|
||||
public void Validate()
|
||||
{
|
||||
foreach (ConfigurationClass configClass in ConfigurationClasses)
|
||||
{
|
||||
configClass.Validate(_problemReporter);
|
||||
}
|
||||
}
|
||||
|
||||
protected void ProcessConfigurationClass(ConfigurationClass configurationClass)
|
||||
{
|
||||
DoProcessConfigurationClass(configurationClass);
|
||||
|
||||
if (ConfigurationClasses.Contains(configurationClass) && configurationClass.ObjectName != null)
|
||||
{
|
||||
// Explicit object definition found, probably replacing an import.
|
||||
// Let's remove the old one and go with the new one.
|
||||
ConfigurationClasses.Remove(configurationClass);
|
||||
}
|
||||
ConfigurationClasses.Add(configurationClass);
|
||||
}
|
||||
|
||||
private void DoProcessConfigurationClass(ConfigurationClass configurationClass)
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportAttribute)) != null)
|
||||
{
|
||||
ImportAttribute attrib = Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportAttribute)) as ImportAttribute;
|
||||
ProcessImport(configurationClass, attrib.Types);
|
||||
}
|
||||
|
||||
if (Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportResourceAttribute)) != null)
|
||||
{
|
||||
ImportResourceAttribute attrib = Attribute.GetCustomAttribute(configurationClass.ConfigurationClassType, typeof(ImportResourceAttribute)) as ImportResourceAttribute;
|
||||
|
||||
foreach (string resource in attrib.Resources)
|
||||
{
|
||||
configurationClass.AddImportedResource(resource, attrib.DefinitionReader);
|
||||
}
|
||||
}
|
||||
|
||||
ISet<MethodInfo> definitionMethods = GetAllMethodsWithCustomAttributeForClass(configurationClass.ConfigurationClassType, typeof(DefinitionAttribute));
|
||||
foreach (MethodInfo definitionMethod in definitionMethods)
|
||||
{
|
||||
configurationClass.Methods.Add(new ConfigurationClassMethod(definitionMethod, configurationClass));
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private ISet<MethodInfo> GetAllMethodsWithCustomAttributeForClass(Type theClass, Type customAttribute)
|
||||
{
|
||||
ISet<MethodInfo> methods = new HashedSet<MethodInfo>();
|
||||
|
||||
foreach (MethodInfo method in theClass.GetMethods())
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(method, customAttribute) != null)
|
||||
{
|
||||
methods.Add(method);
|
||||
}
|
||||
}
|
||||
|
||||
return methods;
|
||||
}
|
||||
|
||||
private void ProcessImport(ConfigurationClass configClass, Type[] classesToImport)
|
||||
{
|
||||
if (_importStack.Contains(configClass))
|
||||
{
|
||||
_problemReporter.Error(new CircularImportProblem(configClass, _importStack, configClass.ConfigurationClassType));
|
||||
}
|
||||
else
|
||||
{
|
||||
_importStack.Push(configClass);
|
||||
foreach (Type classToImport in classesToImport)
|
||||
{
|
||||
ProcessConfigurationClass(new ConfigurationClass(null, classToImport));
|
||||
}
|
||||
_importStack.Pop();
|
||||
}
|
||||
}
|
||||
|
||||
private class CircularImportProblem : Problem
|
||||
{
|
||||
public CircularImportProblem(ConfigurationClass configClass, Stack<ConfigurationClass> importStack, Type configurationClassType)
|
||||
: base(String.Format("A circular @Import has been detected: " +
|
||||
"Illegal attempt by [Configuration] class '{0}' to import class '{1}' as '{2}' is " +
|
||||
"already present in the current import stack [{3}]",
|
||||
importStack.Peek().SimpleName, configClass.SimpleName,
|
||||
configClass.SimpleName, importStack),
|
||||
new Location(importStack.Peek().Resource, configurationClassType)
|
||||
)
|
||||
{ }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Common.Logging;
|
||||
using Spring.Objects.Factory.Parsing;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Collections.Generic;
|
||||
using Spring.Objects.Factory;
|
||||
using Spring.Core;
|
||||
using Spring.Aop.Framework;
|
||||
using Spring.Context.Advice;
|
||||
using Spring.Aop.Framework.DynamicProxy;
|
||||
using Spring.Aop;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
public class ConfigurationClassPostProcessor : IObjectDefinitionRegistryPostProcessor, IOrdered
|
||||
{
|
||||
private ILog _logger = LogManager.GetLogger(typeof(ConfigurationClassPostProcessor));
|
||||
|
||||
private bool _postProcessObjectDefinitionRegistryCalled = false;
|
||||
|
||||
private bool _postProcessObjectFactoryCalled = false;
|
||||
|
||||
private IProblemReporter _problemReporter = new FailFastProblemReporter();
|
||||
|
||||
public int Order
|
||||
{
|
||||
get { return int.MinValue; }
|
||||
}
|
||||
|
||||
public IProblemReporter ProblemReporter
|
||||
{
|
||||
set { _problemReporter = (value ?? new FailFastProblemReporter()); }
|
||||
}
|
||||
|
||||
public void PostProcessObjectDefinitionRegistry(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
if (_postProcessObjectDefinitionRegistryCalled)
|
||||
{
|
||||
throw new InvalidOperationException("PostProcessObjectDefinitionRegistry already called for this post-processor");
|
||||
}
|
||||
if (_postProcessObjectFactoryCalled)
|
||||
{
|
||||
throw new InvalidOperationException("PostProcessObjectFactory already called for this post-processor");
|
||||
}
|
||||
_postProcessObjectDefinitionRegistryCalled = true;
|
||||
ProcessConfigObjectDefinitions(registry);
|
||||
}
|
||||
|
||||
public void PostProcessObjectFactory(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
if (_postProcessObjectFactoryCalled)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"PostProcessObjectFactory already called for this post-processor");
|
||||
}
|
||||
_postProcessObjectFactoryCalled = true;
|
||||
if (!_postProcessObjectDefinitionRegistryCalled)
|
||||
{
|
||||
// ObjectDefinitionRegistryPostProcessor hook apparently not supported...
|
||||
// Simply call processConfigObjectDefinitions lazily at this point then.
|
||||
ProcessConfigObjectDefinitions((IObjectDefinitionRegistry)objectFactory);
|
||||
}
|
||||
|
||||
EnhanceConfigurationClasses(objectFactory);
|
||||
}
|
||||
|
||||
private void EnhanceConfigurationClasses(IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
string[] objectNames = objectFactory.GetObjectDefinitionNames();
|
||||
|
||||
for (int i = 0; i < objectNames.Length; i++)
|
||||
{
|
||||
IObjectDefinition objDef = objectFactory.GetObjectDefinition(objectNames[i]);
|
||||
|
||||
if (((AbstractObjectDefinition)objDef).HasObjectType)
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(objDef.ObjectType, typeof(ConfigurationAttribute)) != null)
|
||||
{
|
||||
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.ProxyTargetAttributes = true;
|
||||
proxyFactory.Interfaces = Type.EmptyTypes;
|
||||
proxyFactory.TargetSource = new ObjectFactoryTargetSource(objectNames[i], objectFactory);
|
||||
SpringObjectMethodInterceptor methodInterceptor = new SpringObjectMethodInterceptor(objectFactory);
|
||||
proxyFactory.AddAdvice(methodInterceptor);
|
||||
|
||||
//TODO check type of object isn't infrastructure type.
|
||||
|
||||
InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(proxyFactory);
|
||||
//iaptb.ProxyDeclaredMembersOnly = true; // make configurable.
|
||||
((IConfigurableObjectDefinition)objDef).ObjectType = iaptb.BuildProxyType();
|
||||
|
||||
objDef.ConstructorArgumentValues.AddIndexedArgumentValue(objDef.ConstructorArgumentValues.ArgumentCount, proxyFactory);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private Type GenerateProxyType(string objectName, IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
ProxyFactory proxyFactory = new ProxyFactory();
|
||||
proxyFactory.ProxyTargetAttributes = true;
|
||||
proxyFactory.Interfaces = Type.EmptyTypes;
|
||||
proxyFactory.TargetSource = new ObjectFactoryTargetSource(objectName, objectFactory);
|
||||
SpringObjectMethodInterceptor methodInterceptor = new SpringObjectMethodInterceptor(objectFactory);
|
||||
proxyFactory.AddAdvice(methodInterceptor);
|
||||
|
||||
//TODO check type of object isn't infrastructure type.
|
||||
|
||||
InheritanceAopProxyTypeBuilder iaptb = new InheritanceAopProxyTypeBuilder(proxyFactory);
|
||||
//iaptb.ProxyDeclaredMembersOnly = true; // make configurable.
|
||||
return iaptb.BuildProxyType();
|
||||
}
|
||||
|
||||
private void ProcessConfigObjectDefinitions(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
ISet<ObjectDefinitionHolder> configCandidates = new HashedSet<ObjectDefinitionHolder>();
|
||||
foreach (string objectName in registry.GetObjectDefinitionNames())
|
||||
{
|
||||
IObjectDefinition objectDef = registry.GetObjectDefinition(objectName);
|
||||
if (ConfigurationClassObjectDefinitionReader.CheckConfigurationClassCandidate(objectDef.ObjectType))
|
||||
{
|
||||
configCandidates.Add(new ObjectDefinitionHolder(objectDef, objectName));
|
||||
}
|
||||
}
|
||||
|
||||
//if nothing to process, bail out
|
||||
if (configCandidates.Count == 0) { return; }
|
||||
|
||||
ConfigurationClassParser parser = new ConfigurationClassParser(_problemReporter);
|
||||
foreach (ObjectDefinitionHolder holder in configCandidates)
|
||||
{
|
||||
IObjectDefinition bd = holder.ObjectDefinition;
|
||||
try
|
||||
{
|
||||
if (bd is AbstractObjectDefinition && ((AbstractObjectDefinition)bd).HasObjectType)
|
||||
{
|
||||
parser.Parse(((AbstractObjectDefinition)bd).ObjectType, holder.ObjectName);
|
||||
}
|
||||
else
|
||||
{
|
||||
//parser.Parse(bd.ObjectTypeName, holder.ObjectName);
|
||||
}
|
||||
}
|
||||
catch (ObjectDefinitionParsingException ex)
|
||||
{
|
||||
throw new ObjectDefinitionStoreException("Failed to load object class: " + bd.ObjectTypeName, ex);
|
||||
}
|
||||
}
|
||||
parser.Validate();
|
||||
|
||||
// Read the model and create Object definitions based on its content
|
||||
ConfigurationClassObjectDefinitionReader reader = new ConfigurationClassObjectDefinitionReader(registry, _problemReporter);
|
||||
reader.LoadObjectDefinitions(parser.ConfigurationClasses);
|
||||
}
|
||||
|
||||
public class ObjectFactoryTargetSource : ITargetSource
|
||||
{
|
||||
private readonly string _objectName;
|
||||
private readonly IConfigurableListableObjectFactory _objectFactory;
|
||||
|
||||
public ObjectFactoryTargetSource(string objectName, IConfigurableListableObjectFactory objectFactory)
|
||||
{
|
||||
_objectName = objectName;
|
||||
_objectFactory = objectFactory;
|
||||
}
|
||||
|
||||
#region ITargetSource Members
|
||||
|
||||
public object GetTarget()
|
||||
{
|
||||
return _objectFactory.GetObject(_objectName);
|
||||
}
|
||||
|
||||
public bool IsStatic
|
||||
{
|
||||
get { return _objectFactory.IsSingleton(_objectName); }
|
||||
}
|
||||
|
||||
public void ReleaseTarget(object target)
|
||||
{
|
||||
}
|
||||
|
||||
public Type TargetType
|
||||
{
|
||||
get { return _objectFactory.GetType(_objectName); }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,96 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Method)]
|
||||
public class DefinitionAttribute : Attribute
|
||||
{
|
||||
private AutoWiringMode _autoWire = AutoWiringMode.No;
|
||||
|
||||
private string _destroyMethod;
|
||||
|
||||
private string _initMethod;
|
||||
|
||||
private string _names;
|
||||
|
||||
/// <summary>
|
||||
/// Are dependencies to be injected via autowiring?
|
||||
/// </summary>
|
||||
/// <value>The auto wire.</value>
|
||||
public AutoWiringMode AutoWire
|
||||
{
|
||||
get { return _autoWire; }
|
||||
set
|
||||
{
|
||||
_autoWire = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The optional name of a method to call on the Object instance upon closing the
|
||||
/// application context, for example a Close() method on a DataSource.
|
||||
/// The method must have no arguments but may throw any exception.
|
||||
/// <para>
|
||||
/// Note: Only invoked on objects whose lifecycle is under the full control of the
|
||||
/// factory, which is always the case for singletons but not guaranteed
|
||||
/// for any other scope.
|
||||
/// </para>
|
||||
/// <see cref="Spring.Context.IConfigurableApplicationContext"/>
|
||||
/// </summary>
|
||||
/// <value>The destroy method.</value>
|
||||
public string DestroyMethod
|
||||
{
|
||||
get { return _destroyMethod; }
|
||||
set
|
||||
{
|
||||
_destroyMethod = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The optional name of a method to call on the object instance during initialization.
|
||||
/// Not commonly used, given that the method may be called programmatically directly
|
||||
/// within the body of a Object-annotated method.
|
||||
/// </summary>
|
||||
/// <value>The init method.</value>
|
||||
public string InitMethod
|
||||
{
|
||||
get { return _initMethod; }
|
||||
set
|
||||
{
|
||||
_initMethod = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The name of this object, or if plural, aliases for this object. If left unspecified
|
||||
/// the name of the object is the name of the attributed method. If specified, the method
|
||||
/// name is ignored.
|
||||
/// </summary>
|
||||
/// <value>The name.</value>
|
||||
public string Names
|
||||
{
|
||||
get
|
||||
{
|
||||
return _names;
|
||||
}
|
||||
set
|
||||
{
|
||||
_names = value;
|
||||
}
|
||||
}
|
||||
|
||||
public string[] NamesToArray
|
||||
{
|
||||
get
|
||||
{
|
||||
return StringUtils.DelimitedListToStringArray(_names, ",");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,45 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// objects on which the current object depends. Any objects specified are guaranteed to be
|
||||
/// created by the container before this object. Used infrequently in cases where a object
|
||||
/// does not explicitly depend on another through properties or constructor arguments,
|
||||
/// but rather depends on the side effects of another object's initialization.
|
||||
/// <para>Note: This attribute will not be inherited by child object definitions,
|
||||
/// hence it needs to be specified per concrete object definition.
|
||||
/// </para>
|
||||
/// <para>Using <see cref="DependsOn"/> at the class level has no effect unless component-scanning
|
||||
/// is being used. If a <see cref="DependsOn"/>-attributed class is declared via XML,
|
||||
/// <see cref="DependsOn"/> attribute metadata is ignored, and
|
||||
/// <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(string[] name)
|
||||
{
|
||||
_name = name;
|
||||
}
|
||||
|
||||
public string[] Name
|
||||
{
|
||||
get { return _name; }
|
||||
set
|
||||
{
|
||||
_name = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates one or more <see cref="Configuration"/> classes to import.
|
||||
///
|
||||
/// <para>Provides functionality equivalent to the :lt;import/> element in Spring XML.
|
||||
/// Only supported for actual <see cref="Configuration"/>-attributed classes.
|
||||
/// </para>
|
||||
///
|
||||
/// <para><see cref="Definition"/> definitions declared in imported <see cref="Configuration"/> classes
|
||||
/// should be accessed by using <see cref="AutoWired"/> injection. Either the object
|
||||
/// itself can be autowired, or the configuration class instance declaring the object can be
|
||||
/// autowired. The latter approach allows for explicit, IDE-friendly navigation between
|
||||
/// <see cref="Configuration"/> class methods.
|
||||
/// </para>
|
||||
///
|
||||
/// <para>If XML or other non-<see cref="Configuration"/> object definition resources need to be
|
||||
/// imported, use <see cref="ImportResource"/>
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ImportAttribute : Attribute
|
||||
{
|
||||
private Type[] _types;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Import class.
|
||||
/// </summary>
|
||||
/// <param name="types"></param>
|
||||
public ImportAttribute(Type[] types)
|
||||
{
|
||||
_types = types;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The <see cref="Configuration"/> class or classes to import.
|
||||
/// </summary>
|
||||
/// <value>The type.</value>
|
||||
public Type[] Types
|
||||
{
|
||||
get { return _types; }
|
||||
set
|
||||
{
|
||||
_types = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class ImportResourceAttribute : Attribute
|
||||
{
|
||||
private Type _objectDefinitionReader = typeof(XmlObjectDefinitionReader);
|
||||
|
||||
private string[] _resources;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ImportResourceAttribute class.
|
||||
/// </summary>
|
||||
/// <param name="resources"></param>
|
||||
public ImportResourceAttribute(string[] resources)
|
||||
{
|
||||
if (resources ==null || resources.Length ==0)
|
||||
throw new ArgumentException("resources cannot be null or empty!");
|
||||
|
||||
_resources = resources;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the ImportResourceAttribute class.
|
||||
/// </summary>
|
||||
/// <param name="resource"></param>
|
||||
public ImportResourceAttribute(string resource)
|
||||
{
|
||||
if (StringUtils.IsNullOrEmpty(resource))
|
||||
throw new ArgumentException("resource cannot be null or empty!");
|
||||
|
||||
_resources = new[] { resource };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// <see cref="IObjectDefinitionReader"/> implementation to use when processing resources specified
|
||||
/// by the <see cref="Resources"/> attribute.
|
||||
/// </summary>
|
||||
/// <value>The <see cref="IObjectDefinitionReader"/>.</value>
|
||||
public Type DefinitionReader
|
||||
{
|
||||
get
|
||||
{
|
||||
return _objectDefinitionReader;
|
||||
}
|
||||
set
|
||||
{
|
||||
if (!((typeof(IObjectDefinitionReader).IsAssignableFrom(value))))
|
||||
throw new ArgumentException(string.Format("DefinitionReader must be of type IObjectDefinitionReader but was of type {0}", value.Name));
|
||||
|
||||
_objectDefinitionReader = value;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resource paths to import. Resource-loading prefixes such as <code>assembly://</code> and
|
||||
/// <code>file://</code>, etc may be used.
|
||||
/// </summary>
|
||||
/// <value>The resources.</value>
|
||||
public string[] Resources
|
||||
{
|
||||
get { return _resources; }
|
||||
set
|
||||
{
|
||||
_resources = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates whether a object is to be lazily initialized.
|
||||
///
|
||||
/// <para>If this annotation is not present on a Component or object definition, eager
|
||||
/// initialization will occur. If present and set to true, the
|
||||
/// object/Component will not be initialized until referenced by another object or
|
||||
/// explicitly retrieved from the enclosing <see cref="Spring.Objects.Factory.IObjectFactory"/>.
|
||||
/// If present and set to false, the object will be instantiated on startup by object factories
|
||||
/// that perform eager initialization of singletons.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// If Lazy is present on a <see cref="Configuration"/> class, this indicates that all
|
||||
/// <see cref="Definition"/> methods within that <see cref="Configuration"/> should be lazily
|
||||
/// initialized. If Lazy is present and false on a object method within a
|
||||
/// Lazy-annotated Configuration class, this indicates overriding the 'default
|
||||
/// lazy' behavior and that the object should be eagerly initialized.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
||||
public class LazyAttribute : Attribute
|
||||
{
|
||||
private bool _lazyInitialize = true;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LazyAttribute class.
|
||||
/// </summary>
|
||||
/// <param name="lazyInitialize"></param>
|
||||
public LazyAttribute(bool lazyInitialize)
|
||||
{
|
||||
_lazyInitialize = lazyInitialize;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the LazyAttribute class.
|
||||
/// </summary>
|
||||
public LazyAttribute()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether lazy initialization should occur.
|
||||
/// </summary>
|
||||
/// <value><c>true</c> if [lazy initialize]; otherwise, <c>false</c>.</value>
|
||||
public bool LazyInitialize
|
||||
{
|
||||
get { return _lazyInitialize; }
|
||||
set
|
||||
{
|
||||
_lazyInitialize = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,23 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// Indicates that an object should be given preference when multiple candidates
|
||||
/// are qualified to autowire a single-valued dependency. If exactly one 'primary'
|
||||
/// object exists among the candidates, it will be the autowired value.
|
||||
///
|
||||
/// <para>Using <see cref="Primary"/> at the class level has no effect unless component-scanning
|
||||
/// is being used. If a <see cref="Primary"/>-attributed class is declared via XML,
|
||||
/// <see cref="Primary"/> attribute metadata is ignored, and
|
||||
/// <code><object primary="true|false"/>></code> is respected instead.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class PrimaryAttribute : Attribute
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// When used as a type-level attribute, indicates the name of a scope to use
|
||||
/// for instances of the attributed type.
|
||||
///
|
||||
/// <para>When used as a method-level attribute in conjunction with the
|
||||
/// <see cref="Definition"/> attribute, indicates the name of a scope to use for
|
||||
/// the instance returned from the method.
|
||||
/// </para>
|
||||
/// <para>In this context, scope means the lifecycle of an instance, such as
|
||||
/// <code>singleton</code>, <code>prototype</code>, and so forth.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class ScopeAttribute : Attribute
|
||||
{
|
||||
private ObjectScope _scope = ObjectScope.Singleton;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the Scope class.
|
||||
/// </summary>
|
||||
/// <param name="scope"></param>
|
||||
public ScopeAttribute(ObjectScope scope)
|
||||
{
|
||||
_scope = scope;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the scope to use for the annotated object.
|
||||
/// </summary>
|
||||
/// <value>The scope.</value>
|
||||
public ObjectScope ObjectScope
|
||||
{
|
||||
get { return _scope; }
|
||||
set
|
||||
{
|
||||
_scope = value;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Util;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Objects.Factory.Config;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
public class AttributeConfigObjectDefinitionParser : IObjectDefinitionParser
|
||||
{
|
||||
/// <summary>
|
||||
/// The object name of the internally managed configuration attribure processor
|
||||
/// </summary>
|
||||
public static readonly string CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME = "Spring.Context.Attributes.InternalConfigurationAttributeProcessor";
|
||||
|
||||
|
||||
private static readonly Type ConfigurationClassPostProcessorType = typeof(ConfigurationClassPostProcessor);
|
||||
|
||||
public AttributeConfigObjectDefinitionParser()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public Objects.Factory.Config.IObjectDefinition ParseElement(System.Xml.XmlElement element, ParserContext parserContext)
|
||||
{
|
||||
IObjectDefinitionRegistry registry = parserContext.ReaderContext.Registry;
|
||||
|
||||
AssertUtils.ArgumentNotNull(registry, "registry");
|
||||
|
||||
if (!registry.ContainsObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME))
|
||||
{
|
||||
RootObjectDefinition objectDefinition = new RootObjectDefinition(ConfigurationClassPostProcessorType);
|
||||
objectDefinition.Role = ObjectRole.ROLE_INFRASTRUCTURE;
|
||||
registry.RegisterObjectDefinition(CONFIGURATION_ATTRIBUTE_PROCESSOR_OBJECT_NAME, objectDefinition);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
public class ComponentScanObjectDefinitionParser
|
||||
{
|
||||
public ComponentScanObjectDefinitionParser()
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,41 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Config
|
||||
{
|
||||
/// <summary>
|
||||
/// <code>NamespaceParser</code> allowing for the configuration of
|
||||
/// declarative transaction management using either XML or using attributes.
|
||||
///
|
||||
/// This namespace handler is the central piece of functionality in the
|
||||
/// Spring transaction management facilities and offers two appraoches
|
||||
/// to declaratively manage transactions.
|
||||
///
|
||||
/// One approach uses transaction semantics defined in XML using the
|
||||
/// <code><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-1.3.xsd"
|
||||
)
|
||||
]
|
||||
public class ContextNamespaceParser : NamespaceParserSupport
|
||||
{
|
||||
/// <summary>
|
||||
/// Register the <see cref="IObjectDefinitionParser"/> for the '<code>advice</code>' and
|
||||
/// '<code>attribute-driven'</code> tags.
|
||||
/// </summary>
|
||||
public override void Init()
|
||||
{
|
||||
RegisterObjectDefinitionParser("attribute-config", new AttributeConfigObjectDefinitionParser());
|
||||
|
||||
//RegisterObjectDefinitionParser("component-scan", new ComponentScanObjectDefinitionParser());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<xsd:schema xmlns="http://www.springframework.net/context"
|
||||
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
|
||||
xmlns:objects="http://www.springframework.net"
|
||||
xmlns:tool="http://www.springframework.net/tool"
|
||||
targetNamespace="http://www.springframework.net/context"
|
||||
elementFormDefault="qualified"
|
||||
attributeFormDefault="unqualified">
|
||||
|
||||
<xsd:import namespace="http://www.springframework.net"/>
|
||||
<xsd:import namespace="http://www.springframework.net/tool"/>
|
||||
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Defines the configuration elements for the Spring Framework's application
|
||||
context support. Effects the activation of various configuration styles
|
||||
for the containing Spring ApplicationContext.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
|
||||
<xsd:element name="attribute-config">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Activates various annotations to be detected in bean classes: Spring's @Required and
|
||||
@Autowired, as well as JSR 250's @PostConstruct, @PreDestroy and @Resource (if available),
|
||||
JAX-WS's @WebServiceRef (if available), EJB3's @EJB (if available), and JPA's
|
||||
@PersistenceContext and @PersistenceUnit (if available). Alternatively, you may
|
||||
choose to activate the individual BeanPostProcessors for those annotations.
|
||||
|
||||
Note: This tag does not activate processing of Spring's @Transactional or EJB3's
|
||||
@TransactionAttribute annotation. Consider the use of the <tx:annotation-driven>
|
||||
tag for that purpose.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:element>
|
||||
|
||||
<xsd:element name="component-scan">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Scans the classpath for annotated components that will be auto-registered as
|
||||
Spring beans. By default, the Spring-provided @Component, @Repository,
|
||||
@Service, and @Controller stereotypes will be detected.
|
||||
|
||||
Note: This tag implies the effects of the 'annotation-config' tag, activating @Required,
|
||||
@Autowired, @PostConstruct, @PreDestroy, @Resource, @PersistenceContext and @PersistenceUnit
|
||||
annotations in the component classes, which is usually desired for autodetected components
|
||||
(without external configuration). Turn off the 'annotation-config' attribute to deactivate
|
||||
this default behavior, for example in order to use custom BeanPostProcessor definitions
|
||||
for handling those annotations.
|
||||
|
||||
Note: You may use placeholders in package paths, but only resolved against system
|
||||
properties (analogous to resource paths). A component scan results in new bean definition
|
||||
being registered; Spring's PropertyPlaceholderConfigurer will apply to those bean
|
||||
definitions just like to regular bean definitions, but it won't apply to the component
|
||||
scan settings themselves.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="attribute-config" type="xsd:boolean"
|
||||
default="true">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
Indicates whether the implicit annotation post-processors should be enabled. Default is "true".
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
<xsd:attribute name="name-generator" type="xsd:string">
|
||||
<xsd:annotation>
|
||||
<xsd:documentation><![CDATA[
|
||||
The fully-qualified class name of the BeanNameGenerator to be used for naming detected components.
|
||||
]]></xsd:documentation>
|
||||
</xsd:annotation>
|
||||
</xsd:attribute>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
|
||||
|
||||
</xsd:schema>
|
||||
@@ -1,87 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.IO;
|
||||
using Common.Logging;
|
||||
using Spring.Context.Attributes;
|
||||
|
||||
namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
public static class AssemblyScanningExtensionMethods
|
||||
{
|
||||
public static void Scan(this IObjectDefinitionRegistry registry, IAssemblyTypeScanner scanner)
|
||||
{
|
||||
IEnumerable<Type> configTypes = scanner.Scan();
|
||||
|
||||
//if we have at least one config class, ensure the post-processor is registered
|
||||
if (configTypes.Count() > 0)
|
||||
{
|
||||
EnsureConfigurationClassPostProcessorIsRegisteredFor(registry);
|
||||
}
|
||||
|
||||
RegisiterDefintionsForTypes(configTypes, registry);
|
||||
}
|
||||
|
||||
public static void Scan(this IObjectDefinitionRegistry registry)
|
||||
{
|
||||
Scan(registry, new AssemblyObjectDefinitionScanner());
|
||||
}
|
||||
|
||||
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Type> typePredicate)
|
||||
{
|
||||
Scan(registry, null, ta => true, typePredicate);
|
||||
}
|
||||
|
||||
public static void Scan(this IObjectDefinitionRegistry registry, string assemblyScanPath, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
|
||||
{
|
||||
//create a scanner instance using the scan path
|
||||
IAssemblyTypeScanner scanner = new AssemblyObjectDefinitionScanner(assemblyScanPath);
|
||||
|
||||
//configure the scanner per the provided constraints
|
||||
scanner.WithAssemblyFilter(assemblyPredicate).WithIncludeFilter(typePredicate);
|
||||
|
||||
//pass the scanner to primary Scan method to actually do the work
|
||||
Scan(registry, scanner);
|
||||
}
|
||||
|
||||
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate, Predicate<Type> typePredicate)
|
||||
{
|
||||
Scan(registry, null, assemblyPredicate, typePredicate);
|
||||
}
|
||||
|
||||
public static void Scan(this IObjectDefinitionRegistry registry, Predicate<Assembly> assemblyPredicate)
|
||||
{
|
||||
Scan(registry, null, assemblyPredicate, t => true);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Ensures the configuration class post processor is registered for.
|
||||
/// </summary>
|
||||
/// <param name="registry">The registry.</param>
|
||||
private static void EnsureConfigurationClassPostProcessorIsRegisteredFor(IObjectDefinitionRegistry registry)
|
||||
{
|
||||
var postProcessorBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
|
||||
if (!registry.ContainsObjectDefinition(postProcessorBuilder.ObjectDefinition.ObjectTypeName))
|
||||
{
|
||||
registry.RegisterObjectDefinition(postProcessorBuilder.ObjectDefinition.ObjectTypeName, postProcessorBuilder.ObjectDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Regisiters the defintions for types.
|
||||
/// </summary>
|
||||
/// <param name="typesToRegister">The types to register.</param>
|
||||
/// <param name="registry">The registry.</param>
|
||||
private static void RegisiterDefintionsForTypes(IEnumerable<Type> typesToRegister, IObjectDefinitionRegistry registry)
|
||||
{
|
||||
foreach (Type type in typesToRegister)
|
||||
{
|
||||
ObjectDefinitionBuilder definition = ObjectDefinitionBuilder.GenericObjectDefinition(type);
|
||||
registry.RegisterObjectDefinition(definition.ObjectDefinition.ObjectTypeName, definition.ObjectDefinition);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Spring.Core.Configuration")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Spring.Core.Configuration")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("aa7c95ac-e82f-4c33-a857-76b179c34166")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,88 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{7B65D538-E863-4F57-8DDC-2C38E4150045}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Spring</RootNamespace>
|
||||
<AssemblyName>Spring.Core.Configuration</AssemblyName>
|
||||
<TargetFrameworkVersion>v3.5</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Common.Logging">
|
||||
<HintPath>..\..\..\lib\Net\2.0\Common.Logging.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Context\Advice\SpringObjectMethodInterceptor.cs" />
|
||||
<Compile Include="Context\Attributes\AssemblyObjectDefinitionScanner.cs" />
|
||||
<Compile Include="Context\Attributes\AssemblyTypeSource.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClass.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassMethod.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassObjectDefinitionReader.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassParser.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassPostProcessor.cs" />
|
||||
<Compile Include="Context\Attributes\DefinitionAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\DependsOnAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ImportAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ImportResourceAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\LazyAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\PrimaryAttribute.cs" />
|
||||
<Compile Include="Context\Attributes\ScopeAttribute.cs" />
|
||||
<Compile Include="Context\Config\AttributeConfigObjectDefinitionParser.cs" />
|
||||
<Compile Include="Context\Config\ComponentScanObjectDefinitionParser.cs" />
|
||||
<Compile Include="Context\Config\ContextNamespaceParser.cs" />
|
||||
<Compile Include="Objects\Factory\Support\AssemblyScanningExtensionMethods.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Context\Config\spring-context-1.3.xsd">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Spring.Aop\Spring.Aop.2010.csproj">
|
||||
<Project>{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}</Project>
|
||||
<Name>Spring.Aop.2010</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Spring.Core\Spring.Core.2010.csproj">
|
||||
<Project>{710961A3-0DF4-49E4-A26E-F5B9C044AC84}</Project>
|
||||
<Name>Spring.Core.2010</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
@@ -1,101 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Spring.Util;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class AssemblyTypeScannerTests
|
||||
{
|
||||
|
||||
private class Scanner : AssemblyTypeScanner
|
||||
{
|
||||
public Scanner(string folderScanPath)
|
||||
: base(folderScanPath)
|
||||
{ }
|
||||
|
||||
public Scanner()
|
||||
: base(null)
|
||||
{ }
|
||||
}
|
||||
|
||||
private Scanner _scanner;
|
||||
|
||||
private List<Predicate<Type>> _excludePredicates
|
||||
{
|
||||
get
|
||||
{
|
||||
//get at the collection of excludePredicates from the private field
|
||||
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
|
||||
return (List<Predicate<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_excludePredicates"));
|
||||
}
|
||||
}
|
||||
|
||||
private List<Predicate<Type>> _includePredicates
|
||||
{
|
||||
get
|
||||
{
|
||||
//get at the collection of includePredicates from the private field
|
||||
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
|
||||
return (List<Predicate<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_includePredicates"));
|
||||
}
|
||||
}
|
||||
|
||||
private List<IEnumerable<Type>> _typeSources
|
||||
{
|
||||
get
|
||||
{
|
||||
//get at the collection of typeSources from the private field
|
||||
//(yuck!-- test smell, but at least its wrapped up in a neat private property getter!)
|
||||
return (List<IEnumerable<Type>>)(ReflectionUtils.GetInstanceFieldValue(_scanner, "_typeSources"));
|
||||
}
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void _TestSetup()
|
||||
{
|
||||
_scanner = new Scanner();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void AssemblyHavingType_T_Adds_Assembly()
|
||||
{
|
||||
_scanner.AssemblyHavingType<Spring.Core.IOrdered>();
|
||||
Assert.That(_typeSources.Any(t => t.Contains(typeof(Spring.Core.IOrdered))));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IncludeType_T_Adds_Type()
|
||||
{
|
||||
_scanner.IncludeType<Spring.Core.IOrdered>();
|
||||
_scanner.IncludeType<Spring.Core.IPriorityOrdered>();
|
||||
|
||||
_includePredicates.Any(p => p(typeof(Spring.Core.IOrdered)));
|
||||
_includePredicates.Any(p => p(typeof(Spring.Core.IPriorityOrdered)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithExcludeFilter_Excludes_Type()
|
||||
{
|
||||
_scanner.IncludeType<TheConfigurationClass>();
|
||||
_scanner.IncludeType<TheImportedConfigurationClass>();
|
||||
_scanner.WithExcludeFilter(t => t.Name.StartsWith("TheImported"));
|
||||
|
||||
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheConfigurationClass))));
|
||||
Assert.False(_scanner.Scan().Contains(typeof(TheImportedConfigurationClass)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithIncludeFilter_Includes_Types()
|
||||
{
|
||||
_scanner.WithIncludeFilter(t => t.Name.Contains("ConfigurationClass"));
|
||||
|
||||
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheConfigurationClass))));
|
||||
Assert.That(_scanner.Scan(), Contains.Item((typeof(TheImportedConfigurationClass))));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,223 +0,0 @@
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Objects.Factory.Support;
|
||||
using Spring.Context.Attributes;
|
||||
using Spring.Objects.Factory.Config;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ConfigurationClassPostProcessorTests
|
||||
{
|
||||
private GenericApplicationContext _ctx;
|
||||
|
||||
[SetUp]
|
||||
public void _SetUp()
|
||||
{
|
||||
_ctx = new GenericApplicationContext();
|
||||
|
||||
var configDefinitionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(TheConfigurationClass));
|
||||
_ctx.RegisterObjectDefinition(configDefinitionBuilder.ObjectDefinition.ObjectTypeName, configDefinitionBuilder.ObjectDefinition);
|
||||
|
||||
var postProcessorDefintionBuilder = ObjectDefinitionBuilder.GenericObjectDefinition(typeof(ConfigurationClassPostProcessor));
|
||||
_ctx.RegisterObjectDefinition(postProcessorDefintionBuilder.ObjectDefinition.ObjectTypeName, postProcessorDefintionBuilder.ObjectDefinition);
|
||||
|
||||
Assert.That(_ctx.ObjectDefinitionCount, Is.EqualTo(2));
|
||||
|
||||
_ctx.Refresh();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Assign_Init_And_Destroy_Methods()
|
||||
{
|
||||
IObjectDefinition def = _ctx.GetObjectDefinition(typeof(ObjectWithInitAndDestroyMethods).Name);
|
||||
|
||||
Assert.That(def, Is.Not.Null);
|
||||
Assert.That(def.InitMethodName, Is.EqualTo("CallToInit"));
|
||||
Assert.That(def.DestroyMethodName, Is.EqualTo("CallToDestroy"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Import_Configurations_From_Additional_Classes()
|
||||
{
|
||||
Assert.That(_ctx.GetObject(typeof(AnImportedType).Name), Is.Not.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Assigned_Aliases()
|
||||
{
|
||||
var firstObject = _ctx["TheFirstAlias"];
|
||||
var secondObject = _ctx["TheSecondAlias"];
|
||||
Assert.That(firstObject, Is.InstanceOf<ObjectWithAnAlias>());
|
||||
Assert.That(secondObject, Is.InstanceOf<ObjectWithAnAlias>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Assigned_Name()
|
||||
{
|
||||
var result = _ctx["TheName"];
|
||||
Assert.That(result, Is.InstanceOf<SingleNamedObject>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Default_Singleton_Scope()
|
||||
{
|
||||
var firstObject = (SingletonParent)_ctx[typeof(SingletonParent).Name];
|
||||
var secondObject = (SingletonParent)_ctx[typeof(SingletonParent).Name];
|
||||
|
||||
Assert.That(firstObject, Is.SameAs(secondObject));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Explicit_PrototypeScope()
|
||||
{
|
||||
var firstObject = (PrototypeChild)_ctx[typeof(PrototypeChild).Name];
|
||||
var secondObject = (PrototypeChild)_ctx[typeof(PrototypeChild).Name];
|
||||
|
||||
Assert.That(firstObject, Is.Not.SameAs(secondObject));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Lazy_Attribute()
|
||||
{
|
||||
Assert.That(_ctx.GetObjectDefinition(typeof(ImplicitLazyInitObject).Name).IsLazyInit, Is.True);
|
||||
Assert.That(_ctx.GetObjectDefinition(typeof(ExplicitLazyInitObject).Name).IsLazyInit, Is.True);
|
||||
Assert.That(_ctx.GetObjectDefinition(typeof(ExplicitNonLazyInitObject).Name).IsLazyInit, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Retreive_Actual_Objects_From_Context()
|
||||
{
|
||||
Assert.That(_ctx[typeof(SingletonParent).Name], Is.TypeOf<SingletonParent>());
|
||||
Assert.That(_ctx[typeof(PrototypeChild).Name], Is.TypeOf<PrototypeChild>());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Satisfy_Dependencies_Of_Objects()
|
||||
{
|
||||
Assert.That(((SingletonParent)_ctx[typeof(SingletonParent).Name]).Child, Is.Not.Null);
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Can_Respect_Imported_Resources()
|
||||
{
|
||||
Assert.That(_ctx["xmlRegisteredObject"], Is.Not.Null);
|
||||
}
|
||||
}
|
||||
|
||||
public class ObjectWithInitAndDestroyMethods
|
||||
{
|
||||
public void CallToDestroy() { }
|
||||
public void CallToInit() { }
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
[Configuration]
|
||||
[ImportResource("assembly://Spring.Core.Configuration.Tests/Spring.Context.Attributes/ObjectDefinitions.xml", DefinitionReader = typeof(XmlObjectDefinitionReader))]
|
||||
public class TheImportedConfigurationClass
|
||||
{
|
||||
[Definition]
|
||||
public virtual AnImportedType AnImportedType()
|
||||
{
|
||||
return new AnImportedType();
|
||||
}
|
||||
}
|
||||
|
||||
[Configuration]
|
||||
[Import(new Type[] { typeof(TheImportedConfigurationClass) })]
|
||||
public class TheConfigurationClass
|
||||
{
|
||||
[Definition(Names = "TheName")]
|
||||
public virtual SingleNamedObject NamedObject()
|
||||
{
|
||||
return new SingleNamedObject();
|
||||
}
|
||||
|
||||
[Definition(DestroyMethod = "CallToDestroy", InitMethod = "CallToInit")]
|
||||
public virtual ObjectWithInitAndDestroyMethods ObjectWithInitAndDestroyMethods()
|
||||
{
|
||||
return new ObjectWithInitAndDestroyMethods();
|
||||
}
|
||||
|
||||
[Definition(Names = "TheFirstAlias,TheSecondAlias")]
|
||||
public virtual ObjectWithAnAlias ObjectWithAnAlias()
|
||||
{
|
||||
return new ObjectWithAnAlias();
|
||||
}
|
||||
|
||||
[Definition]
|
||||
[Scope(ObjectScope.Prototype)]
|
||||
public virtual PrototypeChild PrototypeChild()
|
||||
{
|
||||
return new PrototypeChild();
|
||||
}
|
||||
|
||||
[Definition]
|
||||
public virtual SingletonParent SingletonParent()
|
||||
{
|
||||
return new SingletonParent(PrototypeChild());
|
||||
}
|
||||
|
||||
[Definition]
|
||||
[Lazy]
|
||||
public virtual ImplicitLazyInitObject ImplicitLazyInitObject()
|
||||
{
|
||||
return new ImplicitLazyInitObject();
|
||||
}
|
||||
|
||||
[Definition]
|
||||
[Lazy(true)]
|
||||
public virtual ExplicitLazyInitObject ExplicitLazyInitObject()
|
||||
{
|
||||
return new ExplicitLazyInitObject();
|
||||
}
|
||||
|
||||
[Definition]
|
||||
[Lazy(false)]
|
||||
public virtual ExplicitNonLazyInitObject ExplicitNonLazyInitObject()
|
||||
{
|
||||
return new ExplicitNonLazyInitObject();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class TypeRegisteredInXml { }
|
||||
|
||||
public class AnImportedType { }
|
||||
|
||||
public class ImplicitLazyInitObject { }
|
||||
|
||||
public class ExplicitLazyInitObject { }
|
||||
|
||||
public class ExplicitNonLazyInitObject { }
|
||||
|
||||
public class ObjectWithAnAlias { }
|
||||
|
||||
public class SingleNamedObject { }
|
||||
|
||||
public class SingletonParent
|
||||
{
|
||||
private PrototypeChild _child;
|
||||
|
||||
public SingletonParent(PrototypeChild child)
|
||||
{
|
||||
_child = child;
|
||||
}
|
||||
|
||||
public PrototypeChild Child
|
||||
{
|
||||
get
|
||||
{
|
||||
return _child;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class PrototypeChild { }
|
||||
}
|
||||
@@ -1,38 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Spring.Context.Attributes;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class DefinitionAttributeTests
|
||||
{
|
||||
[Test]
|
||||
public void Can_Accept_Single_Name()
|
||||
{
|
||||
var def = new DefinitionAttribute();
|
||||
|
||||
def.Names = "Steve";
|
||||
|
||||
Assert.That(def.NamesToArray[0], Is.EqualTo("Steve"));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void Can_Accept_Multiple_Names()
|
||||
{
|
||||
var def = new DefinitionAttribute();
|
||||
var names = "Name1,Name2,Name3";
|
||||
|
||||
def.Names = names;
|
||||
Assert.That(def.NamesToArray[0], Is.EqualTo("Name1"));
|
||||
Assert.That(def.NamesToArray[1], Is.EqualTo("Name2"));
|
||||
Assert.That(def.NamesToArray[2], Is.EqualTo("Name3"));
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using Spring.Objects.Factory.Xml;
|
||||
using Spring.Objects.Factory.Support;
|
||||
|
||||
namespace Spring.Context.Attributes
|
||||
{
|
||||
[TestFixture]
|
||||
public class ImportResourceAttributeTests
|
||||
{
|
||||
[Test]
|
||||
public void Uses_XmlObjectDefinitionReader_By_Default()
|
||||
{
|
||||
var attrib = new ImportResourceAttribute("the resource");
|
||||
|
||||
Assert.That(attrib.DefinitionReader, Is.EqualTo(typeof(XmlObjectDefinitionReader)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Assign_NonDefault_DefinitionReader()
|
||||
{
|
||||
var attrib = new ImportResourceAttribute("the resource");
|
||||
attrib.DefinitionReader = typeof(AbstractObjectDefinitionReader);
|
||||
|
||||
Assert.That(attrib.DefinitionReader, Is.EqualTo(typeof(AbstractObjectDefinitionReader)));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DefinitionReader_Can_Prevent_Improper_Types()
|
||||
{
|
||||
ImportResourceAttribute attrib = new ImportResourceAttribute("the resource");
|
||||
|
||||
try
|
||||
{
|
||||
attrib.DefinitionReader = typeof(Object);// <--need to use *anything* ensured *not* to implement IObjectDefinitionReader
|
||||
Assert.Fail("Expected Exception of type ArgumentException not thrown!");
|
||||
}
|
||||
catch (ArgumentException)
|
||||
{
|
||||
//swallow the expected exception
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<objects xmlns="http://www.springframework.net">
|
||||
<object id="xmlRegisteredObject" type="Spring.Context.Attributes.TypeRegisteredInXml, Spring.Core.Configuration.Tests" />
|
||||
</objects>
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using NUnit.Framework;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using Spring.Context.Config;
|
||||
using Spring.Context.Support;
|
||||
using Spring.Context.Attributes;
|
||||
|
||||
namespace Spring.Objects.Factory.Support
|
||||
{
|
||||
[TestFixture]
|
||||
public class AssemblyScanningExtensionMethodsTests
|
||||
{
|
||||
private GenericApplicationContext _context;
|
||||
|
||||
[SetUp]
|
||||
public void _TestSetup()
|
||||
{
|
||||
_context = new GenericApplicationContext();
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Assembly_Based_On_Assembly_Metadata()
|
||||
{
|
||||
_context.Scan(a => a.GetName().Name.StartsWith("Spring.Core.Configuration."));
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Assembly_Containing_Specific_Type_But_Having_NO_Definitions()
|
||||
{
|
||||
//specifically filter assemblies for one that we *know* will result in NO [Configuration] types in it
|
||||
_context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(Spring.Core.IOrdered).Name)));
|
||||
_context.Refresh();
|
||||
|
||||
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Assembly_Containing_Specific_Type()
|
||||
{
|
||||
_context.Scan(assy => assy.GetTypes().Any(type => type.FullName.Contains(typeof(MarkerTypeForScannerToFind).Name)));
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Specific_Type()
|
||||
{
|
||||
_context.Scan(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name));
|
||||
_context.Refresh();
|
||||
|
||||
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(4));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Specific_Types_With_Compound_Predicate()
|
||||
{
|
||||
_context.Scan(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name) || ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Filter_For_Specific_Types_With_Multiple_Include_Filters()
|
||||
{
|
||||
var scanner = new AssemblyObjectDefinitionScanner();
|
||||
scanner.WithIncludeFilter(type => ((Type)type).FullName.Contains(typeof(TheImportedConfigurationClass).Name));
|
||||
scanner.WithIncludeFilter(type => ((Type)type).FullName.Contains(typeof(TheConfigurationClass).Name));
|
||||
|
||||
_context.Scan(scanner);
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Perform_Scan_With_No_Filtering()
|
||||
{
|
||||
_context.Scan();
|
||||
_context.Refresh();
|
||||
|
||||
AssertExpectedObjectsAreRegisteredWith(_context);
|
||||
}
|
||||
|
||||
private void AssertExpectedObjectsAreRegisteredWith(GenericApplicationContext _context)
|
||||
{
|
||||
Assert.That(_context.DefaultListableObjectFactory.ObjectDefinitionCount, Is.EqualTo(13));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public class MarkerTypeForScannerToFind
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// General Information about an assembly is controlled through the following
|
||||
// set of attributes. Change these attribute values to modify the information
|
||||
// associated with an assembly.
|
||||
[assembly: AssemblyTitle("Spring.Core.Configuration.Tests")]
|
||||
[assembly: AssemblyDescription("")]
|
||||
[assembly: AssemblyConfiguration("")]
|
||||
[assembly: AssemblyCompany("Microsoft")]
|
||||
[assembly: AssemblyProduct("Spring.Core.Configuration.Tests")]
|
||||
[assembly: AssemblyCopyright("Copyright © Microsoft 2010")]
|
||||
[assembly: AssemblyTrademark("")]
|
||||
[assembly: AssemblyCulture("")]
|
||||
|
||||
// Setting ComVisible to false makes the types in this assembly not visible
|
||||
// to COM components. If you need to access a type in this assembly from
|
||||
// COM, set the ComVisible attribute to true on that type.
|
||||
[assembly: ComVisible(false)]
|
||||
|
||||
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||
[assembly: Guid("65e12092-0586-435f-b9ef-e4a35c302bef")]
|
||||
|
||||
// Version information for an assembly consists of the following four values:
|
||||
//
|
||||
// Major Version
|
||||
// Minor Version
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
// You can specify all the values or you can default the Build and Revision Numbers
|
||||
// by using the '*' as shown below:
|
||||
// [assembly: AssemblyVersion("1.0.*")]
|
||||
[assembly: AssemblyVersion("1.0.0.0")]
|
||||
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||
@@ -1,85 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||
<ProductVersion>8.0.30703</ProductVersion>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
<ProjectGuid>{4F1A206C-09A8-43FF-B791-FE956E99A120}</ProjectGuid>
|
||||
<OutputType>Library</OutputType>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<RootNamespace>Spring</RootNamespace>
|
||||
<AssemblyName>Spring.Core.Configuration.Tests</AssemblyName>
|
||||
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
|
||||
<FileAlignment>512</FileAlignment>
|
||||
<TargetFrameworkProfile />
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DebugSymbols>true</DebugSymbols>
|
||||
<DebugType>full</DebugType>
|
||||
<Optimize>false</Optimize>
|
||||
<OutputPath>bin\Debug\</OutputPath>
|
||||
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DebugType>pdbonly</DebugType>
|
||||
<Optimize>true</Optimize>
|
||||
<OutputPath>bin\Release\</OutputPath>
|
||||
<DefineConstants>TRACE</DefineConstants>
|
||||
<ErrorReport>prompt</ErrorReport>
|
||||
<WarningLevel>4</WarningLevel>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="nunit.framework, Version=2.5.7.10213, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
|
||||
<HintPath>..\..\..\lib\Net\2.0\nunit.framework.dll</HintPath>
|
||||
</Reference>
|
||||
<Reference Include="System" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Context\Attributes\AssemblyTypeScannerTests.cs" />
|
||||
<Compile Include="Context\Attributes\ConfigurationClassPostProcessorTests.cs" />
|
||||
<Compile Include="Context\Attributes\DefinitionAttributeTests.cs" />
|
||||
<Compile Include="Context\Attributes\ImportResourceAttributeTests.cs" />
|
||||
<Compile Include="Context\Config\ContextNamespaceParserTests.cs" />
|
||||
<Compile Include="Objects\Factory\Support\AssemblyScanningExtensionMethodsTests.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\..\src\Spring\Spring.Aop\Spring.Aop.2010.csproj">
|
||||
<Project>{3A3A4E65-45A6-4B20-B460-0BEDC302C02C}</Project>
|
||||
<Name>Spring.Aop.2010</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\src\Spring\Spring.Core.Configuration\Spring.Core.Configuration.2010.csproj">
|
||||
<Project>{7B65D538-E863-4F57-8DDC-2C38E4150045}</Project>
|
||||
<Name>Spring.Core.Configuration.2010</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\..\..\src\Spring\Spring.Core\Spring.Core.2010.csproj">
|
||||
<Project>{710961A3-0DF4-49E4-A26E-F5B9C044AC84}</Project>
|
||||
<Name>Spring.Core.2010</Name>
|
||||
</ProjectReference>
|
||||
<ProjectReference Include="..\Spring.Core.Tests\Spring.Core.Tests.2010.csproj">
|
||||
<Project>{44B16BAA-6DF8-447C-9D7F-3AD3D854D904}</Project>
|
||||
<Name>Spring.Core.Tests.2010</Name>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Context\Attributes\ObjectDefinitions.xml" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Context\Config\ContextNamespaceParserTests.xml">
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
|
||||
Other similar extension points exist, see Microsoft.Common.targets.
|
||||
<Target Name="BeforeBuild">
|
||||
</Target>
|
||||
<Target Name="AfterBuild">
|
||||
</Target>
|
||||
-->
|
||||
</Project>
|
||||
Reference in New Issue
Block a user