#164 add working metadata caching

This commit is contained in:
Marko Lahma
2018-10-21 14:12:29 +03:00
parent 1fdb0622b7
commit 13fb3c74b8
70 changed files with 1405 additions and 1256 deletions

View File

@@ -3,6 +3,7 @@
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_FOREACH/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_IFELSE/@EntryValue">Required</s:String>
<s:String x:Key="/Default/CodeStyle/CodeFormatting/CSharpCodeStyle/BRACES_FOR_WHILE/@EntryValue">Required</s:String>
<s:Boolean x:Key="/Default/CodeStyle/CodeFormatting/CSharpFormat/USE_INDENT_FROM_VS/@EntryValue">False</s:Boolean>
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderRegionName/@EntryValue">License</s:String>
<s:String x:Key="/Default/CodeStyle/FileHeader/FileHeaderText/@EntryValue">/*&#xD;
* Copyright 2018 the original author or authors.&#xD;

View File

@@ -18,15 +18,10 @@
#endregion
#region Imports
using System;
using System.Reflection;
using Spring.Aop;
#endregion
namespace Spring.AopQuickStart.Aspects
{
/// <summary>
@@ -39,8 +34,7 @@ namespace Spring.AopQuickStart.Aspects
{
public void AfterThrowing(Exception ex)
{
Console.Error.WriteLine(
String.Format("Advised method threw this exception : {0}", ex.Message));
Console.Error.WriteLine($"Advised method threw this exception : {ex.Message}");
}
}
}

View File

@@ -18,16 +18,10 @@
#endregion
#region Imports
using System;
using AopAlliance.Intercept;
using Spring.AopQuickStart.Attributes;
#endregion
namespace Spring.AopQuickStart.Aspects
{
/// <summary>

View File

@@ -1,29 +1,27 @@
using System;
using System.Reflection;
using AopAlliance.Intercept;
using Spring.Aop.Framework;
namespace Spring.AopQuickStart
{
public class ModificationAdvice : IMethodInterceptor
{
public virtual Object Invoke(IMethodInvocation invocation)
public virtual object Invoke(IMethodInvocation invocation)
{
MethodInfo method = invocation.Method;
object proxy = invocation.Proxy;
if (proxy is IIsModified)
if (proxy is IIsModified obj)
{
IIsModified obj = (IIsModified) proxy;
if (IsSetter(method))
{
obj.IsModified = HasModificationOccured(method, invocation.This, invocation.Arguments);
}
}
return invocation.Proceed();
}
private bool HasModificationOccured(MethodInfo setter, Object target, Object[] args)
private bool HasModificationOccured(MethodInfo setter, object target, object[] args)
{
PropertyInfo property = target.GetType().GetProperty(setter.Name.Substring(4));
@@ -31,25 +29,25 @@ namespace Spring.AopQuickStart
{
// modification check is unimportant
// for write only methods
Object newVal = args[0];
Object oldVal = property.GetValue(target, null);
object newVal = args[0];
object oldVal = property.GetValue(target, null);
if ((newVal == null) && (oldVal == null))
if (newVal == null && (oldVal == null))
{
return false;
}
else if ((newVal == null) && (oldVal != null))
if (newVal == null && (oldVal != null))
{
return true;
}
else if ((newVal != null) && (oldVal == null))
if ((oldVal == null))
{
return true;
}
else
{
return (!newVal.Equals(oldVal));
}
return (!newVal.Equals(oldVal));
}
return false;
@@ -57,8 +55,7 @@ namespace Spring.AopQuickStart
private bool IsSetter(MethodInfo method)
{
return (method.Name.StartsWith("set_")) && (method.GetParameters().Length == 1);
return method.Name.StartsWith("set_") && method.GetParameters().Length == 1;
}
}
}
}

View File

@@ -18,18 +18,12 @@
#endregion
#region Imports
using System;
using System.Collections.Generic;
using Spring.Context;
using Spring.Context.Support;
using Spring.AopQuickStart.Commands;
#endregion
namespace Spring.AopQuickStart
{
/// <summary>
@@ -47,7 +41,7 @@ namespace Spring.AopQuickStart
{
// Create AOP proxy using Spring.NET IoC container.
IApplicationContext ctx = ContextRegistry.GetContext();
IDictionary<string, ICommand> commands = ctx.GetObjects<ICommand>();
var commands = ctx.GetObjects<ICommand>();
foreach (ICommand command in commands.Values)
{

View File

@@ -18,10 +18,7 @@
#endregion
#region Imports
using System;
using System.Collections.Generic;
using System.Data;
using NUnit.Framework;
using Spring.Aop.Config;
@@ -34,8 +31,6 @@ using Spring.Objects.Factory.Xml;
using Spring.Transaction.Config;
using Spring.TxQuickStart.Services;
#endregion
namespace Spring.TxQuickStart
{
[TestFixture]
@@ -54,7 +49,6 @@ namespace Spring.TxQuickStart
NamespaceParserRegistry.RegisterParser(typeof(TxNamespaceParser));
NamespaceParserRegistry.RegisterParser(typeof(AopNamespaceParser));
IApplicationContext context = CreateContextFromXml();
IDictionary<string, IAccountManager> dict = context.GetObjects<IAccountManager>();
accountManager = context["accountManager"] as IAccountManager;
CleanDb(context);
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2011 the original author or authors.
* Copyright <20> 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -153,11 +153,11 @@ namespace Spring.Aop.Framework.AutoProxy
/// </returns>
protected IList<IAdvisor> FindEligibleAdvisors(Type targetType, string targetName)
{
IList<IAdvisor> candidateAdvisors = FindCandidateAdvisors(targetType, targetName);
IList<IAdvisor> eligibleAdvisors = FindAdvisorsThatCanApply(candidateAdvisors, targetType, targetName);
List<IAdvisor> candidateAdvisors = FindCandidateAdvisors(targetType, targetName);
List<IAdvisor> eligibleAdvisors = FindAdvisorsThatCanApply(candidateAdvisors, targetType, targetName);
ExtendAdvisors(eligibleAdvisors, targetType, targetName);
eligibleAdvisors = SortAdvisors(eligibleAdvisors);
SortAdvisors(eligibleAdvisors);
return eligibleAdvisors;
}
@@ -168,7 +168,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="targetType">the type of the object to be advised</param>
/// <param name="targetName">the name of the object to be advised</param>
/// <returns>the list of candidate advisors</returns>
protected virtual IList<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
protected virtual List<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
{
return _advisorRetrievalHelper.FindAdvisorObjects(targetType, targetName);
}
@@ -181,7 +181,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="targetType">the target object's type</param>
/// <param name="targetName">the target object's name</param>
/// <returns>the list of applicable advisors</returns>
protected virtual IList<IAdvisor> FindAdvisorsThatCanApply(IList<IAdvisor> candidateAdvisors, Type targetType, string targetName)
protected virtual List<IAdvisor> FindAdvisorsThatCanApply(List<IAdvisor> candidateAdvisors, Type targetType, string targetName)
{
if (candidateAdvisors.Count==0)
{
@@ -195,7 +195,7 @@ namespace Spring.Aop.Framework.AutoProxy
{
if (logger.IsInfoEnabled)
{
logger.Info(string.Format("Candidate advisor [{0}] accepted for targetType [{1}]", candidate, targetType));
logger.Info($"Candidate advisor [{candidate}] accepted for targetType [{targetType}]");
}
eligibleAdvisors.Add(candidate);
}
@@ -210,7 +210,7 @@ namespace Spring.Aop.Framework.AutoProxy
{
if (logger.IsInfoEnabled)
{
logger.Info(string.Format("Candidate advisor [{0}] accepted for targetType [{1}]", candidate, targetType));
logger.Info($"Candidate advisor [{candidate}] accepted for targetType [{targetType}]");
}
eligibleAdvisors.Add(candidate);
}
@@ -218,7 +218,7 @@ namespace Spring.Aop.Framework.AutoProxy
{
if (logger.IsInfoEnabled)
{
logger.Info(string.Format("Candidate advisor [{0}] rejected for targetType [{1}]", candidate, targetType));
logger.Info($"Candidate advisor [{candidate}] rejected for targetType [{targetType}]");
}
}
}
@@ -231,20 +231,9 @@ namespace Spring.Aop.Framework.AutoProxy
/// </summary>
/// <param name="advisors">The advisors.</param>
/// <returns></returns>
protected virtual IList<IAdvisor> SortAdvisors(IList<IAdvisor> advisors)
protected virtual void SortAdvisors(List<IAdvisor> advisors)
{
if (advisors.Count==0)
{
return advisors;
}
if (advisors is List<IAdvisor>)
((List<IAdvisor>)advisors).Sort(new OrderComparator<IAdvisor>());
else if (advisors is ArrayList)
((ArrayList) advisors).Sort(new OrderComparator());
else if (advisors is Array)
Array.Sort((Array) advisors, new OrderComparator());
return advisors;
advisors.Sort(OrderComparator<IAdvisor>.Instance);
}
/// <summary>

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2011 the original author or authors.
* Copyright <20> 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -41,10 +41,11 @@ namespace Spring.Aop.Framework.AutoProxy
/// <summary>
/// Separator between prefix and remainder of object name
/// </summary>
public static readonly string SEPARATOR = ".";
public const string Separator = ".";
private bool usePrefix;
private string advisorObjectNamePrefix;
private IList<IAdvisor> cachedAdvisors;
private List<IAdvisor> cachedAdvisors;
#region Properties
@@ -94,7 +95,7 @@ namespace Spring.Aop.Framework.AutoProxy
// If no infrastructure object name prefix has been set, override it.
if (advisorObjectNamePrefix == null)
{
advisorObjectNamePrefix = value + SEPARATOR;
advisorObjectNamePrefix = value + Separator;
}
}
}
@@ -107,7 +108,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="targetType">the type of the object to be advised</param>
/// <param name="targetName">the name of the object to be advised</param>
/// <returns>the list of candidate advisors</returns>
protected override IList<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
protected override List<IAdvisor> FindCandidateAdvisors(Type targetType, string targetName)
{
if (cachedAdvisors == null) {
cachedAdvisors = base.FindCandidateAdvisors(targetType, targetName);

View File

@@ -13,6 +13,6 @@ namespace Spring.Aop.Framework.AutoProxy
/// <summary>
/// Get the list of advisor objects to apply on the target.
/// </summary>
IList<IAdvisor> FindAdvisorObjects(Type targetType, string targetName);
List<IAdvisor> FindAdvisorObjects(Type targetType, string targetName);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright <20> 2002-2011 the original author or authors.
* Copyright <20> 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -155,7 +155,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// </remarks>
public void PostProcessObjectFactory(IConfigurableListableObjectFactory factory)
{
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames();
var objectDefinitionNames = factory.GetObjectDefinitionNames();
for (int i = 0; i < objectDefinitionNames.Count; ++i)
{
string name = objectDefinitionNames[i];

View File

@@ -63,7 +63,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// <param name="targetType">the type of the object to be advised</param>
/// <param name="targetName">the name of the object to be advised</param>
/// <returns>A list of eligible <see cref="IAdvisor"/> instances</returns>
public virtual IList<IAdvisor> FindAdvisorObjects(Type targetType, string targetName)
public virtual List<IAdvisor> FindAdvisorObjects(Type targetType, string targetName)
{
IList<string> advisorNames = GetAdvisorCandidateNames(targetType, targetName);

View File

@@ -15,7 +15,6 @@
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Runtime.Serialization;
@@ -606,15 +605,15 @@ namespace Spring.Aop.Framework
/// <summary> Add all global interceptors and pointcuts.</summary>
private void AddGlobalAdvisor(IListableObjectFactory objectFactory, string prefix)
{
IList<string> globalAspectNames =
var globalAspectNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisors));
IList<string> globalAdvisorNames =
var globalAdvisorNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisor));
IList<string> globalInterceptorNames =
var globalInterceptorNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IInterceptor));
List<object> objects = new List<object>();
Dictionary<object, string> names = new Dictionary<object, string>();
for (int i = 0; i < globalAspectNames.Count; i++)
{
string name = globalAspectNames[i];
@@ -656,7 +655,7 @@ namespace Spring.Aop.Framework
names[obj] = name;
}
}
objects.Sort(new OrderComparator());
objects.Sort(OrderComparator.Instance);
foreach (object obj in objects)
{
string name = names[obj];
@@ -716,11 +715,11 @@ namespace Spring.Aop.Framework
/// <summary> Add all global introductions.</summary>
private void AddGlobalIntroduction(IListableObjectFactory objectFactory, string prefix)
{
IList<string> globalAspectNames =
var globalAspectNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisors));
IList<string> globalAdvisorNames =
var globalAdvisorNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvisor));
IList<string> globalIntroductionNames =
var globalIntroductionNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(objectFactory, typeof(IAdvice));
List<object> objects = new List<object>();
Dictionary<object, string> names = new Dictionary<object, string>();
@@ -770,7 +769,7 @@ namespace Spring.Aop.Framework
}
}
}
objects.Sort(new OrderComparator());
objects.Sort(OrderComparator.Instance);
for (var i = 0; i < objects.Count; i++)
{
object obj = objects[i];

View File

@@ -117,7 +117,7 @@ namespace Spring.Context.Attributes
{
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer(objectFactory);
IList<string> objectNames = objectFactory.GetObjectDefinitionNames();
var objectNames = objectFactory.GetObjectDefinitionNames();
foreach (string name in objectNames)
{

View File

@@ -497,13 +497,13 @@ namespace Spring.Context.Support
}
}
IDictionary<string, IObjectDefinitionRegistryPostProcessor> objectMap = objectFactory.GetObjects<IObjectDefinitionRegistryPostProcessor>(true, false);
var objectMap = objectFactory.GetObjects<IObjectDefinitionRegistryPostProcessor>(true, false);
List<IObjectDefinitionRegistryPostProcessor> registryPostProcessorObjects = null;
if (objectMap.Count > 0)
{
registryPostProcessorObjects = new List<IObjectDefinitionRegistryPostProcessor>(objectMap.Values);
registryPostProcessorObjects.Sort(new OrderComparator<IObjectDefinitionRegistryPostProcessor>());
registryPostProcessorObjects.Sort(OrderComparator<IObjectDefinitionRegistryPostProcessor>.Instance);
foreach (var processor in registryPostProcessorObjects)
{
processor.PostProcessObjectDefinitionRegistry(registry);
@@ -535,7 +535,7 @@ namespace Spring.Context.Support
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
IList<string> factoryProcessorNames = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false);
var factoryProcessorNames = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false);
// Separate between ObjectFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
@@ -573,7 +573,7 @@ namespace Spring.Context.Support
{
orderedFactoryProcessors.Add(SafeGetObjectFactory().GetObject<IObjectFactoryPostProcessor>(orderedFactoryProcessorsName));
}
orderedFactoryProcessors.Sort(new OrderComparator<IObjectFactoryPostProcessor>());
orderedFactoryProcessors.Sort(OrderComparator<IObjectFactoryPostProcessor>.Instance);
InvokeObjectFactoryPostProcessors(orderedFactoryProcessors, SafeGetObjectFactory());
// and then the unordered ones...
@@ -595,19 +595,21 @@ namespace Spring.Context.Support
}
protected virtual void InvokePriorityOrderedObjectFactoryPostProcessors(
IList<string> factoryProcessorNames,
IReadOnlyList<string> factoryProcessorNames,
List<IObjectFactoryPostProcessor> priorityOrderedFactoryProcessors)
{
priorityOrderedFactoryProcessors.Sort(new OrderComparator<IObjectFactoryPostProcessor>());
priorityOrderedFactoryProcessors.Sort(OrderComparator<IObjectFactoryPostProcessor>.Instance);
InvokeObjectFactoryPostProcessors(priorityOrderedFactoryProcessors, SafeGetObjectFactory());
var processorNames = factoryProcessorNames.Count > 0 ? new HashSet<string>(factoryProcessorNames) : null;
// Now will find any additional IObjectFactoryPostProcessors that implement IPriorityOrdered that may have been
// resolved due to using TypeAlias
IList<string> factoryProcessorNamesAfterTypeAlias = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false);
var factoryProcessorNamesAfterTypeAlias = GetObjectNamesForType(typeof(IObjectFactoryPostProcessor), true, false);
priorityOrderedFactoryProcessors.Clear();
foreach (string factoryProcessorName in factoryProcessorNamesAfterTypeAlias)
{
if (!factoryProcessorNames.Contains(factoryProcessorName))
if (processorNames == null || !processorNames.Contains(factoryProcessorName))
{
if (IsTypeMatch(factoryProcessorName, typeof(IPriorityOrdered)))
{
@@ -616,7 +618,7 @@ namespace Spring.Context.Support
}
}
// Second, invoke newly discovered IObjectFactoryPostProcessors that implement IPriorityOrdered.
priorityOrderedFactoryProcessors.Sort(new OrderComparator<IObjectFactoryPostProcessor>());
priorityOrderedFactoryProcessors.Sort(OrderComparator<IObjectFactoryPostProcessor>.Instance);
InvokeObjectFactoryPostProcessors(priorityOrderedFactoryProcessors, SafeGetObjectFactory());
}
@@ -637,21 +639,20 @@ namespace Spring.Context.Support
private void RegisterObjectPostProcessors(IConfigurableListableObjectFactory objectFactory)
{
RefreshObjectPostProcessorChecker(objectFactory);
IDictionary<string, IObjectPostProcessor> dict = GetObjects<IObjectPostProcessor>(true, false);
var dict = GetObjects<IObjectPostProcessor>(true, false);
List<IObjectPostProcessor> objectProcessors = new List<IObjectPostProcessor>(dict.Values);
// objectProcessors.Sort(new OrderComparator());
foreach (IObjectPostProcessor objectPostProcessor in objectProcessors)
for (var i = 0; i < objectProcessors.Count; i++)
{
IObjectPostProcessor objectPostProcessor = objectProcessors[i];
SafeGetObjectFactory().AddObjectPostProcessor(objectPostProcessor);
}
if (log.IsDebugEnabled)
{
log.Debug(string.Format(
CultureInfo.InvariantCulture,
"processed {0} IObjectPostProcessors defined in application context [{1}].",
objectProcessors.Count,
Name));
log.Debug(
$"processed {objectProcessors.Count} IObjectPostProcessors defined in application context [{Name}].");
}
}
@@ -704,12 +705,11 @@ namespace Spring.Context.Support
if (log.IsDebugEnabled)
{
log.Debug(string.Format(
"No IEventRegistry found with name '{0}' : using default '{1}'.",
EventRegistryObjectName, EventRegistry));
log.Debug(
$"No IEventRegistry found with name '{EventRegistryObjectName}' : using default '{EventRegistry}'.");
}
}
ICollection<IEventRegistryAware> interestedParties = GetObjects<IEventRegistryAware>(true, false).Values;
var interestedParties = GetObjects<IEventRegistryAware>(true, false).Values;
foreach (IEventRegistryAware party in interestedParties)
{
party.EventRegistry = EventRegistry;
@@ -816,7 +816,7 @@ namespace Spring.Context.Support
private void RefreshApplicationEventListeners()
{
ICollection<IApplicationEventListener> listeners = GetObjects<IApplicationEventListener>(true, false).Values;
var listeners = GetObjects<IApplicationEventListener>(true, false).Values;
foreach (IApplicationEventListener applicationListener in listeners)
{
EventRegistry.Subscribe(applicationListener);
@@ -1125,7 +1125,7 @@ namespace Spring.Context.Support
/// are defined.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectNamesForType(Type)"/>
public IList<string> GetObjectNamesForType(Type type)
public IReadOnlyList<string> GetObjectNamesForType(Type type)
{
return SafeGetObjectFactory().GetObjectNamesForType(type);
}
@@ -1153,7 +1153,7 @@ namespace Spring.Context.Support
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNames<T>()
public IReadOnlyList<string> GetObjectNames<T>()
{
return GetObjectNamesForType(typeof(T));
}
@@ -1179,7 +1179,7 @@ namespace Spring.Context.Support
/// are defined.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectNamesForType(Type, bool, bool)"/>
public IList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
return SafeGetObjectFactory().GetObjectNamesForType(type, includePrototypes, includeFactoryObjects);
}
@@ -1208,18 +1208,18 @@ namespace Spring.Context.Support
/// for all object names.
/// </typeparam>
/// <param name="includePrototypes">
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// </param>
/// <param name="includeFactoryObjects">
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// </param>
/// <returns>
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
{
return GetObjectNamesForType(typeof(T), includePrototypes, includeFactoryObjects);
}
@@ -1232,7 +1232,7 @@ namespace Spring.Context.Support
/// are defined.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames()"/>
public IList<string> GetObjectDefinitionNames()
public IReadOnlyList<string> GetObjectDefinitionNames()
{
return GetObjectDefinitionNames(false);
}
@@ -1246,7 +1246,7 @@ namespace Spring.Context.Support
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
public IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestors)
{
return SafeGetObjectFactory().GetObjectDefinitionNames(includeAncestors);
}
@@ -1316,7 +1316,7 @@ namespace Spring.Context.Support
/// If the objects could not be created.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectsOfType(Type)"/>
public IDictionary<string, object> GetObjectsOfType(Type type)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type)
{
return GetObjectsOfType(type, true, true);
}
@@ -1348,7 +1348,7 @@ namespace Spring.Context.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, T> GetObjects<T>()
public IReadOnlyDictionary<string, T> GetObjects<T>()
{
return SafeGetObjectFactory().GetObjects<T>(true, true);
}
@@ -1380,7 +1380,7 @@ namespace Spring.Context.Support
/// If the objects could not be created.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectsOfType(Type, bool, bool)"/>
public IDictionary<string, object> GetObjectsOfType(
public IReadOnlyDictionary<string, object> GetObjectsOfType(
Type type, bool includePrototypes, bool includeFactoryObjects)
{
return SafeGetObjectFactory().GetObjectsOfType(type, includePrototypes, includeFactoryObjects);
@@ -1412,7 +1412,7 @@ namespace Spring.Context.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
{
return SafeGetObjectFactory().GetObjects<T>(includePrototypes, includeFactoryObjects);
}
@@ -1448,7 +1448,7 @@ namespace Spring.Context.Support
/// </exception>
public T GetObject<T>()
{
IList<string> objectNamesForType = GetObjectNamesForType(typeof(T));
var objectNamesForType = GetObjectNamesForType(typeof(T));
if ((objectNamesForType == null) || (objectNamesForType.Count == 0))
{
throw new NoSuchObjectDefinitionException(typeof(T).FullName, "Requested Type not Defined in the Context.");
@@ -1456,7 +1456,8 @@ namespace Spring.Context.Support
if (objectNamesForType.Count > 1)
{
throw new ObjectDefinitionStoreException(string.Format("More than one definition for {0} found in the Context.", typeof(T).FullName));
throw new ObjectDefinitionStoreException(
$"More than one definition for {typeof(T).FullName} found in the Context.");
}
return (T)GetObject(objectNamesForType[0]);
@@ -1520,7 +1521,7 @@ namespace Spring.Context.Support
/// If there's no such object definition.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IObjectFactory.GetAliases(string)"/>
public IList<string> GetAliases(string name)
public IReadOnlyList<string> GetAliases(string name)
{
return SafeGetObjectFactory().GetAliases(name);
}

View File

@@ -1,7 +1,5 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,14 +14,8 @@
* limitations under the License.
*/
#endregion
#region Imports
using System.Reflection;
#endregion
namespace Spring.Core
{
/// <summary>
@@ -39,7 +31,6 @@ namespace Spring.Core
/// <author>Rick Evans</author>
public class CriteriaMemberFilter
{
#region Constructor (s) / Destructor
/// <summary>
/// Creates a new instance of the
/// <see cref="CriteriaMemberFilter"/> class.
@@ -47,9 +38,7 @@ namespace Spring.Core
public CriteriaMemberFilter ()
{
}
#endregion
#region Methods
/// <summary>
/// Returns true if the supplied <see cref="System.Reflection.MemberInfo"/> instance
/// satisfies the supplied <paramref name="filterCriteria"/> (which must be an
@@ -75,6 +64,5 @@ namespace Spring.Core
ICriteria criteria = filterCriteria as ICriteria;
return criteria.IsSatisfied (member);
}
#endregion
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -62,6 +62,8 @@ namespace Spring.Core
[Serializable]
public class OrderComparator<T> : IComparer<T>
{
public static readonly IComparer<T> Instance = new OrderComparator<T>();
/// <summary>
/// Compares two objects and returns a value indicating whether one is less than,
/// equal to or greater than the other.
@@ -81,20 +83,19 @@ namespace Spring.Core
{
IOrdered o1lhs = o1 as IOrdered;
IOrdered o2rhs = o2 as IOrdered;
int lhs = o1lhs != null ? o1lhs.Order : Int32.MaxValue;
int rhs = o2rhs != null ? o2rhs.Order : Int32.MaxValue;
int lhs = o1lhs?.Order ?? int.MaxValue;
int rhs = o2rhs?.Order ?? int.MaxValue;
if (lhs < rhs)
{
return - 1;
}
else if (lhs > rhs)
if (lhs > rhs)
{
return 1;
}
else
{
return CompareEqualOrder(o1, o2);
}
return CompareEqualOrder(o1, o2);
}
/// <summary>

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -31,6 +31,7 @@ using Spring.Objects.Factory.Config;
using Common.Logging;
using Spring.Objects.Factory.Support;
using Spring.Util;
namespace Spring.Objects.Factory.Attributes
{
@@ -66,19 +67,20 @@ namespace Spring.Objects.Factory.Attributes
/// thus the latter configuration will override the former for properties wired through
/// both approaches.
/// </summary>
public class AutowiredAttributeObjectPostProcessor : InstantiationAwareObjectPostProcessorAdapter, IObjectFactoryAware, IOrdered
public class AutowiredAttributeObjectPostProcessor
: InstantiationAwareObjectPostProcessorAdapter, IMergedObjectDefinitionPostProcessor, IObjectFactoryAware, IOrdered
{
private static readonly ILog logger = LogManager.GetLogger<AutowiredAttributeObjectPostProcessor>();
private int order = int.MaxValue - 2;
private IConfigurableListableObjectFactory objectFactory;
private static IConfigurableListableObjectFactory objectFactory;
private readonly HashSet<string> lookupMethodsChecked = new HashSet<string>();
private readonly SynchronizedHashtable candidateConstructorsCache = new SynchronizedHashtable();
private readonly IDictionary<Type, InjectionMetadata> injectionMetadataCache = new Dictionary<Type, InjectionMetadata>();
private readonly Dictionary<string, InjectionMetadata> injectionMetadataCache = new Dictionary<string, InjectionMetadata>();
private readonly IList<Type> autowiredPropertyTypes = new List<Type>();
private readonly List<Type> autowiredPropertyTypes = new List<Type>();
/// <summary>
/// Return the order value of this object, where a higher value means greater in
@@ -95,11 +97,7 @@ namespace Spring.Objects.Factory.Attributes
/// <returns>
/// The order value.
/// </returns>
public int Order
{
get { return order; }
private set { order = value; }
}
public int Order { get; private set; } = int.MaxValue - 2;
/// <summary>
/// Callback that supplies the owning factory to an object instance.
@@ -120,7 +118,19 @@ namespace Spring.Objects.Factory.Attributes
/// </exception>
public IObjectFactory ObjectFactory
{
set { objectFactory = (IConfigurableListableObjectFactory) value; }
set => objectFactory = (IConfigurableListableObjectFactory) value;
}
public void PostProcessMergedObjectDefinition(RootObjectDefinition objectDefinition, Type objectType, string objectName)
{
var metadata = FindAutowiringMetadata(objectName, objectType, null);
metadata.CheckConfigMembers(objectDefinition);
}
public void ResetObjectDefinition(string beanName)
{
this.lookupMethodsChecked.Remove(beanName);
injectionMetadataCache.Remove(beanName);
}
/// <summary>
@@ -154,6 +164,40 @@ namespace Spring.Objects.Factory.Attributes
/// <exception cref="ObjectsException">in case of errors</exception>
public override ConstructorInfo[] DetermineCandidateConstructors(Type objectType, string objectName)
{
/* TODO implement Lookup
// Let's check for lookup methods here..
if (!lookupMethodsChecked.Contains(objectName))
{
try
{
foreach (var method in objectType.GetMethods())
{
ValueAttribute lookup = method.GetCustomAttribute<ValueAttribute>(true);
if (lookup != null)
{
AssertUtils.State(objectFactory != null, "No ObjectFactory available");
var lookupMethodOverride = new LookupMethodOverride(method.Name, lookup.Expression);
try
{
var mbd = (RootObjectDefinition) objectFactory.GetMergedObjectDefinition(objectName);
mbd.MethodOverrides.Add(lookupMethodOverride);
}
catch (NoSuchObjectDefinitionException)
{
throw new ObjectCreationException(objectName,
"Cannot apply @Lookup to objects without corresponding object definition");
}
}
};
}
catch (Exception ex)
{
throw new ObjectCreationException(objectName, "Lookup method resolution failed", ex);
}
lookupMethodsChecked.Add(objectName);
}*/
// Quick check on the concurrent map first, with minimal locking.
ConstructorInfo[] candidateConstructors = candidateConstructorsCache.ContainsKey(objectType)
? (ConstructorInfo[]) candidateConstructorsCache[objectType]
@@ -173,9 +217,7 @@ namespace Spring.Objects.Factory.Attributes
ConstructorInfo defaultConstructor = null;
foreach (var candidate in rawCandidates)
{
AutowiredAttribute attr =
Attribute.GetCustomAttribute(candidate, typeof (AutowiredAttribute)) as AutowiredAttribute;
if (attr != null)
if (Attribute.GetCustomAttribute(candidate, typeof (AutowiredAttribute)) is AutowiredAttribute attr)
{
if (requiredConstructor != null)
{
@@ -249,7 +291,7 @@ namespace Spring.Objects.Factory.Attributes
var objectDefinition = objectFactory.GetObjectDefinition(objectName) as RootObjectDefinition;
if (objectType != null)
{
var metadata = FindAutowiringMetadata(objectType);
var metadata = FindAutowiringMetadata(objectName, objectType, null);
metadata.CheckConfigMembers(objectDefinition);
}
return null;
@@ -267,7 +309,7 @@ namespace Spring.Objects.Factory.Attributes
public override IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, IList<PropertyInfo> pis,
object objectInstance, string objectName)
{
var metadata = FindAutowiringMetadata(objectInstance.GetType());
var metadata = FindAutowiringMetadata(objectName, objectInstance.GetType(), pvs);
try
{
metadata.Inject(objectInstance, objectName, pvs);
@@ -279,22 +321,25 @@ namespace Spring.Objects.Factory.Attributes
return pvs;
}
private InjectionMetadata FindAutowiringMetadata(Type objectType)
private InjectionMetadata FindAutowiringMetadata(string objectName, Type objectType, IPropertyValues pvs)
{
InjectionMetadata metadata;
if (injectionMetadataCache.TryGetValue(objectType, out metadata))
// Fall back to class name as cache key, for backwards compatibility with custom callers.
var cacheKey = StringUtils.HasLength(objectName) ? objectName : objectType.Name;
injectionMetadataCache.TryGetValue(cacheKey, out var metadata);
if (InjectionMetadata.NeedsRefresh(metadata, objectType))
{
return metadata;
}
lock (injectionMetadataCache)
{
if (!injectionMetadataCache.TryGetValue(objectType, out metadata))
lock (injectionMetadataCache)
{
metadata = BuildAutowiringMetadata(objectType);
injectionMetadataCache.Add(objectType, metadata);
if (!injectionMetadataCache.TryGetValue(cacheKey, out metadata)
|| InjectionMetadata.NeedsRefresh(metadata, objectType))
{
metadata = BuildAutowiringMetadata(objectType);
injectionMetadataCache[cacheKey] = metadata;
}
}
}
return metadata;
}
@@ -304,71 +349,77 @@ namespace Spring.Objects.Factory.Attributes
do
{
foreach (var autowiredType in autowiredPropertyTypes)
for (var i = 0; i < autowiredPropertyTypes.Count; i++)
{
var autowiredType = autowiredPropertyTypes[i];
var currElements = new List<InjectionMetadata.InjectedElement>();
foreach (
var property in
objectType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public |
BindingFlags.Instance))
var properties =
objectType.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (var property in properties)
{
var required = true;
var attr = Attribute.GetCustomAttribute(property, autowiredType);
if (attr is AutowiredAttribute)
if (attr is AutowiredAttribute autowiredAttribute)
{
required = ((AutowiredAttribute) attr).Required;
required = autowiredAttribute.Required;
}
if (attr != null && property.DeclaringType == objectType)
{
currElements.Add(new AutowiredPropertyElement(property, required));
currElements.Add(new AutowiredPropertyElement(this, property, required));
}
}
foreach (
var field in
objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
var fields = objectType.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (var field in fields)
{
var required = true;
var attr = Attribute.GetCustomAttribute(field, autowiredType);
if (attr is AutowiredAttribute)
if (attr is AutowiredAttribute autowiredAttribute)
{
required = ((AutowiredAttribute) attr).Required;
required = autowiredAttribute.Required;
}
if (attr != null && field.DeclaringType == objectType)
{
currElements.Add(new AutowiredFieldElement(field, required));
currElements.Add(new AutowiredFieldElement(this, field, required));
}
}
foreach (
var method in
objectType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance))
var methods = objectType.GetMethods(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance);
foreach (var method in methods)
{
var required = true;
var attr = Attribute.GetCustomAttribute(method, autowiredType);
if (attr is AutowiredAttribute)
if (attr is AutowiredAttribute autowiredAttribute)
{
required = ((AutowiredAttribute) attr).Required;
required = autowiredAttribute.Required;
}
if (attr != null && method.DeclaringType == objectType)
{
if (method.IsStatic)
{
logger.Warn(
m => m("Autowired annotation is not supported on static methods: " + method.Name));
logger.Warn(m => m("Autowired annotation is not supported on static methods: " + method.Name));
continue;
}
if (method.IsGenericMethod)
{
logger.Warn(
m => m("Autowired annotation is not supported on generic methods: " + method.Name));
logger.Warn(m => m("Autowired annotation is not supported on generic methods: " + method.Name));
continue;
}
currElements.Add(new AutowiredMethodElement(method, required));
currElements.Add(new AutowiredMethodElement(this, method, required));
}
}
elements.InsertRange(0, currElements);
}
objectType = objectType.BaseType;
} while (objectType != null && objectType != typeof (Object));
} while (objectType != null && objectType != typeof (object));
return new InjectionMetadata(objectType, elements);
}
@@ -376,7 +427,7 @@ namespace Spring.Objects.Factory.Attributes
/// <summary>
/// Register the specified bean as dependent on the autowired beans.
/// </summary>
private static void RegisterDependentObjects(string objectName, IList autowiredObjectNames)
private void RegisterDependentObjects(string objectName, List<string> autowiredObjectNames)
{
if (objectName == null)
{
@@ -392,34 +443,29 @@ namespace Spring.Objects.Factory.Attributes
var dependsOn = new List<string>(objectDefinition.DependsOn);
foreach (var name in autowiredObjectNames)
{
var autowiredObjectName = name as string;
var autowiredObjectName = name;
if (!dependsOn.Contains(autowiredObjectName))
{
dependsOn.Add(autowiredObjectName);
logger.Debug(
m =>
m("Autowiring by type from object name '{0}' to object named '{1}'", objectName,
autowiredObjectName));
logger.Debug(m => m("Autowiring by type from object name '{0}' to object named '{1}'", objectName, autowiredObjectName));
}
}
objectDefinition.DependsOn = dependsOn;
}
private static object ResolvedCachedArgument(String objectName, Object cachedArgument)
private object ResolvedCachedArgument(string objectName, object cachedArgument)
{
if (cachedArgument is DependencyDescriptor)
if (cachedArgument is DependencyDescriptor descriptor)
{
var descriptor = (DependencyDescriptor) cachedArgument;
return objectFactory.ResolveDependency(descriptor, objectName, null);
}
else if (cachedArgument is RuntimeObjectReference)
if (cachedArgument is RuntimeObjectReference runtimeObjectReference)
{
return objectFactory.GetObject(((RuntimeObjectReference) cachedArgument).ObjectName);
}
else
{
return cachedArgument;
return objectFactory.GetObject(runtimeObjectReference.ObjectName);
}
return cachedArgument;
}
/// <summary>
@@ -427,58 +473,58 @@ namespace Spring.Objects.Factory.Attributes
/// </summary>
private class AutowiredPropertyElement : InjectionMetadata.InjectedElement
{
private readonly bool _required;
private readonly AutowiredAttributeObjectPostProcessor processor;
private readonly bool required;
private bool cached;
private object cachedFieldValue;
private bool _cached = false;
private Object _cachedFieldValue;
public AutowiredPropertyElement(PropertyInfo property, bool required)
public AutowiredPropertyElement(AutowiredAttributeObjectPostProcessor processor, PropertyInfo property, bool required)
: base(property)
{
_required = required;
this.processor = processor;
this.required = required;
}
public override void Inject(Object instance, String objectName, IPropertyValues pvs)
public override void Inject(object instance, string objectName, IPropertyValues pvs)
{
var property = (PropertyInfo) Member;
try
{
Object value;
if (_cached)
object value;
if (cached)
{
value = ResolvedCachedArgument(objectName, _cachedFieldValue);
value = processor.ResolvedCachedArgument(objectName, cachedFieldValue);
}
else
{
var descriptor = new DependencyDescriptor(property, _required);
var descriptor = new DependencyDescriptor(property, required);
var autowiredObjectNames = new List<string>();
value = objectFactory.ResolveDependency(descriptor, objectName, autowiredObjectNames);
value = processor.objectFactory.ResolveDependency(descriptor, objectName, autowiredObjectNames);
lock (this)
{
if (!_cached)
if (!cached)
{
if (value != null || _required)
if (value != null || required)
{
_cachedFieldValue = descriptor;
RegisterDependentObjects(objectName, autowiredObjectNames);
cachedFieldValue = descriptor;
processor.RegisterDependentObjects(objectName, autowiredObjectNames);
if (autowiredObjectNames.Count == 1)
{
var autowiredBeanName = autowiredObjectNames[0];
if (objectFactory.ContainsObject(autowiredBeanName))
if (processor.objectFactory.ContainsObject(autowiredBeanName))
{
if (objectFactory.IsTypeMatch(autowiredBeanName, property.GetType()))
if (processor.objectFactory.IsTypeMatch(autowiredBeanName, property.GetType()))
{
_cachedFieldValue = new RuntimeObjectReference(autowiredBeanName);
cachedFieldValue = new RuntimeObjectReference(autowiredBeanName);
}
}
}
}
else
{
_cachedFieldValue = null;
cachedFieldValue = null;
}
_cached = true;
cached = true;
}
}
}
@@ -499,58 +545,58 @@ namespace Spring.Objects.Factory.Attributes
/// </summary>
private class AutowiredFieldElement : InjectionMetadata.InjectedElement
{
private readonly bool _required;
private readonly AutowiredAttributeObjectPostProcessor processor;
private readonly bool required;
private bool cached;
private object cachedFieldValue;
private bool _cached = false;
private Object _cachedFieldValue;
public AutowiredFieldElement(FieldInfo field, bool required)
public AutowiredFieldElement(AutowiredAttributeObjectPostProcessor processor, FieldInfo field, bool required)
: base(field)
{
_required = required;
this.processor = processor;
this.required = required;
}
public override void Inject(Object instance, String objectName, IPropertyValues pvs)
public override void Inject(object instance, string objectName, IPropertyValues pvs)
{
var field = (FieldInfo) Member;
try
{
Object value;
if (_cached)
object value;
if (cached)
{
value = ResolvedCachedArgument(objectName, _cachedFieldValue);
value = processor.ResolvedCachedArgument(objectName, cachedFieldValue);
}
else
{
var descriptor = new DependencyDescriptor(field, _required);
var descriptor = new DependencyDescriptor(field, required);
var autowiredObjectNames = new List<string>();
value = objectFactory.ResolveDependency(descriptor, objectName, autowiredObjectNames);
value = processor.objectFactory.ResolveDependency(descriptor, objectName, autowiredObjectNames);
lock (this)
{
if (!_cached)
if (!cached)
{
if (value != null || _required)
if (value != null || required)
{
_cachedFieldValue = descriptor;
RegisterDependentObjects(objectName, autowiredObjectNames);
cachedFieldValue = descriptor;
processor.RegisterDependentObjects(objectName, autowiredObjectNames);
if (autowiredObjectNames.Count == 1)
{
var autowiredBeanName = autowiredObjectNames[0] as string;
if (objectFactory.ContainsObject(autowiredBeanName))
if (processor.objectFactory.ContainsObject(autowiredBeanName))
{
if (objectFactory.IsTypeMatch(autowiredBeanName, field.GetType()))
if (processor.objectFactory.IsTypeMatch(autowiredBeanName, field.GetType()))
{
_cachedFieldValue = new RuntimeObjectReference(autowiredBeanName);
cachedFieldValue = new RuntimeObjectReference(autowiredBeanName);
}
}
}
}
else
{
_cachedFieldValue = null;
cachedFieldValue = null;
}
_cached = true;
cached = true;
}
}
}
@@ -571,40 +617,40 @@ namespace Spring.Objects.Factory.Attributes
///
private class AutowiredMethodElement : InjectionMetadata.InjectedElement
{
private readonly bool _required;
private readonly AutowiredAttributeObjectPostProcessor processor;
private readonly bool required;
private bool cached;
private volatile object[] cachedMethodArguments;
private bool _cached = false;
private volatile Object[] _cachedMethodArguments;
public AutowiredMethodElement(MethodInfo method, bool required)
public AutowiredMethodElement(AutowiredAttributeObjectPostProcessor processor, MethodInfo method, bool required)
: base(method)
{
_required = required;
this.processor = processor;
this.required = required;
}
public override void Inject(Object target, string objectName, IPropertyValues pvs)
public override void Inject(object target, string objectName, IPropertyValues pvs)
{
MethodInfo method = Member as MethodInfo;
try
{
Object[] arguments;
if (_cached)
object[] arguments;
if (cached)
{
arguments = ResolveCachedArguments(objectName);
}
else
{
Type[] paramTypes = method.GetParameters().Select(p => p.ParameterType).ToArray();
arguments = new Object[paramTypes.Length];
arguments = new object[paramTypes.Length];
var descriptors = new DependencyDescriptor[paramTypes.Length];
var autowiredBeanNames = new List<string>();
for (int i = 0; i < arguments.Length; i++)
{
MethodParameter methodParam = new MethodParameter(method, i);
descriptors[i] = new DependencyDescriptor(methodParam, _required);
arguments[i] = objectFactory.ResolveDependency(descriptors[i], objectName, autowiredBeanNames);
if (arguments[i] == null && !_required)
descriptors[i] = new DependencyDescriptor(methodParam, required);
arguments[i] = processor.objectFactory.ResolveDependency(descriptors[i], objectName, autowiredBeanNames);
if (arguments[i] == null && !required)
{
arguments = null;
break;
@@ -612,26 +658,26 @@ namespace Spring.Objects.Factory.Attributes
}
lock (this)
{
if (!_cached)
if (!cached)
{
if (arguments != null)
{
_cachedMethodArguments = new Object[arguments.Length];
cachedMethodArguments = new object[arguments.Length];
for (int i = 0; i < arguments.Length; i++)
{
_cachedMethodArguments[i] = descriptors[i];
cachedMethodArguments[i] = descriptors[i];
}
RegisterDependentObjects(objectName, autowiredBeanNames);
processor.RegisterDependentObjects(objectName, autowiredBeanNames);
if (autowiredBeanNames.Count == paramTypes.Length)
{
for (int i = 0; i < paramTypes.Length; i++)
{
string autowiredBeanName = autowiredBeanNames[i] as string;
if (objectFactory.ContainsObject(autowiredBeanName))
if (processor.objectFactory.ContainsObject(autowiredBeanName))
{
if (objectFactory.IsTypeMatch(autowiredBeanName, paramTypes[i]))
if (processor.objectFactory.IsTypeMatch(autowiredBeanName, paramTypes[i]))
{
_cachedMethodArguments[i] =
cachedMethodArguments[i] =
new RuntimeObjectReference(autowiredBeanName);
}
}
@@ -640,9 +686,9 @@ namespace Spring.Objects.Factory.Attributes
}
else
{
_cachedMethodArguments = null;
cachedMethodArguments = null;
}
_cached = true;
cached = true;
}
}
}
@@ -657,16 +703,16 @@ namespace Spring.Objects.Factory.Attributes
}
}
private Object[] ResolveCachedArguments(string objectName)
private object[] ResolveCachedArguments(string objectName)
{
if (_cachedMethodArguments == null)
if (cachedMethodArguments == null)
{
return null;
}
Object[] arguments = new Object[_cachedMethodArguments.Length];
object[] arguments = new object[cachedMethodArguments.Length];
for (int i = 0; i < arguments.Length; i++)
{
arguments[i] = ResolvedCachedArgument(objectName, _cachedMethodArguments[i]);
arguments[i] = processor.ResolvedCachedArgument(objectName, cachedMethodArguments[i]);
}
return arguments;
}

View File

@@ -22,96 +22,93 @@ using System;
using System.Collections.Generic;
using System.Reflection;
using Common.Logging;
using Spring.Objects.Factory.Support;
namespace Spring.Objects.Factory.Attributes
{
/// <summary>
/// Internal class for managing injection metadata.
/// Not intended for direct use in applications.
/// </summary>
public class InjectionMetadata
{
private static readonly ILog Logger = LogManager.GetLogger<InjectionMetadata>();
/// <summary>
/// Internal class for managing injection metadata.
/// Not intended for direct use in applications.
/// </summary>
public class InjectionMetadata
{
private static readonly ILog Logger = LogManager.GetLogger<InjectionMetadata>();
private readonly IList<InjectedElement> _injectedElements;
private readonly Type targetType;
private readonly IList<InjectedElement> _injectedElements;
/// <summary>
/// </summary>
/// <param name="targetType"></param>
/// <param name="elements"></param>
public InjectionMetadata(Type targetType, IList<InjectedElement> elements)
{
this.targetType = targetType;
_injectedElements = new List<InjectedElement>();
if (elements.Count > 0)
{
foreach (var element in elements)
{
Logger.Debug(m => m("Found injected element on class [" + targetType.Name + "]: " + element));
_injectedElements.Add(element);
}
}
}
/// <summary>
/// </summary>
/// <param name="targetType"></param>
/// <param name="elements"></param>
public InjectionMetadata(Type targetType, IList<InjectedElement> elements)
{
_injectedElements = new List<InjectedElement>();
if (elements.Count > 0)
{
foreach (var element in elements)
{
Logger.Debug(m => m("Found injected element on class [" + targetType.Name + "]: " + element));
_injectedElements.Add(element);
}
}
}
/// <summary>
/// </summary>
/// <param name="objectDefinition"></param>
public void CheckConfigMembers(RootObjectDefinition objectDefinition)
{
}
/// <summary>
/// </summary>
/// <param name="objectDefinition"></param>
public void CheckConfigMembers(RootObjectDefinition objectDefinition)
{
}
/// <summary>
/// Inject values for members into object instance
/// </summary>
/// <param name="instance"></param>
/// <param name="objectName"></param>
/// <param name="pvs"></param>
public void Inject(object instance, string objectName, IPropertyValues pvs)
{
for (var i = 0; i < _injectedElements.Count; i++)
{
var element = _injectedElements[i];
Logger.Debug(m => m("Processing injected method of bean '{0}': {1}", objectName, element));
element.Inject(instance, objectName, pvs);
}
}
/// <summary>
/// Represents an element that needs to be injected
/// </summary>
public abstract class InjectedElement
{
/// <summary>
/// Instantiates a new inject element
/// </summary>
/// <param name="member"></param>
protected InjectedElement(MemberInfo member)
{
Member = member;
}
/// <summary>
/// Inject values for members into object instance
/// </summary>
/// <param name="instance"></param>
/// <param name="objectName"></param>
/// <param name="pvs"></param>
public void Inject(Object instance, string objectName, IPropertyValues pvs)
{
if (_injectedElements.Count == 0)
return;
/// <summary>
/// The Property, field, method or constructor info.
/// </summary>
public MemberInfo Member { get; }
foreach(var element in _injectedElements)
{
Logger.Debug(m => m("Processing injected method of bean '{0}': {1}", objectName, element));
element.Inject(instance, objectName, pvs);
}
}
/// <summary>
/// Ececuted to inject value to associated memeber info
/// </summary>
/// <param name="target"></param>
/// <param name="requestingObjectName"></param>
/// <param name="pvs"></param>
public abstract void Inject(object target, string requestingObjectName, IPropertyValues pvs);
}
/// <summary>
/// Represents an element that needs to be injected
/// </summary>
public abstract class InjectedElement
{
/// <summary>
/// The Property, field, method or constructor info
/// </summary>
private readonly MemberInfo _member;
/// <summary>
/// Instantiates a new inject element
/// </summary>
/// <param name="member"></param>
protected InjectedElement(MemberInfo member)
{
_member = member;
}
public MemberInfo Member
{
get { return _member; }
}
/// <summary>
/// Ececuted to inject value to associated memeber info
/// </summary>
/// <param name="target"></param>
/// <param name="requestingObjectName"></param>
/// <param name="pvs"></param>
public abstract void Inject(object target, string requestingObjectName, IPropertyValues pvs);
}
}
public static bool NeedsRefresh(InjectionMetadata metadata, Type type)
{
return (metadata == null || metadata.targetType != type);
}
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,12 +16,6 @@
* limitations under the License.
*/
#endregion
#region Imports
#endregion
using System;
@@ -154,12 +148,12 @@ namespace Spring.Objects.Factory.Config
/// ApplicationContext instance that the object is living in.
/// <para>
/// Note there are no such default types registered in a plain IObjectFactory,
/// not even for the BeanFactory interface itself.
/// not even for the IObjectFactory interface itself.
/// </para>
/// </remarks>
/// <param name="dependencyType">Type of the dependency to register.
/// This will typically be a base interface such as IObjectFactory, with extensions of it resolved
/// as well if declared as an autowiring dependency (e.g. IListableBeanFactory),
/// as well if declared as an autowiring dependency (e.g. IListableObjectFactory),
/// as long as the given value actually implements the extended interface.
/// </param>
/// <param name="autowiredValue">The autowired value. This may also be an
@@ -169,7 +163,7 @@ namespace Spring.Objects.Factory.Config
/// <summary>
/// Determines whether the specified object qualifies as an autowire candidate,
/// to be injected into other beans which declare a dependency of matching type.
/// to be injected into other objects which declare a dependency of matching type.
/// This method checks ancestor factories as well.
/// </summary>
/// <param name="objectName">Name of the object to check.</param>
@@ -179,5 +173,33 @@ namespace Spring.Objects.Factory.Config
/// </returns>
/// <exception cref="NoSuchObjectDefinitionException">if there is no object with the given name.</exception>
bool IsAutowireCandidate(string objectName, DependencyDescriptor descriptor);
/// <summary>
/// Clear the merged object definition cache, removing entries for objects
/// which are not considered eligible for full metadata caching yet.
/// </summary>
/// <remarks>
/// Typically triggered after changes to the original object definitions,
/// e.g. after applying a <see cref="IObjectFactoryPostProcessor" />. Note that metadata
/// for objects which have already been created at this point will be kept around.
/// </remarks>
/// <seealso cref="GetObjectDefinition(string)"/>
void ClearMetadataCache();
/// <summary>
/// Freeze all object definitions, signalling that the registered object definitions
/// will not be modified or post-processed any further.
/// </summary>
/// <remarks>
/// This allows the factory to aggressively cache object definition metadata.
/// </remarks>
void FreezeConfiguration();
/// <summary>
/// Return whether this factory's object definitions are frozen,
/// i.e. are not supposed to be modified or post-processed any further.
/// </summary>
bool ConfigurationFrozen { get; }
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,10 @@
#endregion
#region Imports
using System;
using System.ComponentModel;
using Spring.Util;
#endregion
namespace Spring.Objects.Factory.Config
{
/// <summary>

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,5 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,18 +14,12 @@
* limitations under the License.
*/
#endregion
#region Imports
using System;
using System.Collections.Generic;
using Spring.Objects.Factory.Xml;
using Spring.Util;
#endregion
namespace Spring.Objects.Factory.Config
{
/// <summary>
@@ -55,11 +47,9 @@ namespace Spring.Objects.Factory.Config
[Serializable]
public class ObjectDefinitionHolder
{
private IObjectDefinition objectDefinition;
private string objectName;
private IList<string> aliases;
#region Constructor () / Destructor
private readonly IObjectDefinition objectDefinition;
private readonly string objectName;
private readonly List<string> aliases;
/// <summary>
/// Creates a new instance of the
@@ -88,33 +78,27 @@ namespace Spring.Objects.Factory.Config
/// Any aliases for the supplied <paramref name="definition"/>
/// </param>
public ObjectDefinitionHolder(
IObjectDefinition definition, string name, IList<string> aliases)
IObjectDefinition definition,
string name,
IReadOnlyList<string> aliases)
{
this.objectDefinition = definition;
this.objectName = name;
this.aliases = aliases ?? new List<string>(0);
objectDefinition = definition;
objectName = name;
this.aliases = aliases != null && aliases.Count > 0
? new List<string>(aliases)
: null;
}
#endregion
#region Properties
/// <summary>
/// The <see cref="Spring.Objects.Factory.Config.IObjectDefinition"/> held by this
/// instance.
/// </summary>
public IObjectDefinition ObjectDefinition
{
get { return objectDefinition; }
}
public IObjectDefinition ObjectDefinition => objectDefinition;
/// <summary>
/// The name of the object definition.
/// </summary>
public string ObjectName
{
get { return objectName; }
}
public string ObjectName => objectName;
/// <summary>
/// Any aliases for the object definition.
@@ -127,10 +111,7 @@ namespace Spring.Objects.Factory.Config
/// <see cref="System.String"/> array will be returned.
/// </p>
/// </remarks>
public IList<string> Aliases
{
get { return aliases; }
}
public IReadOnlyList<string> Aliases => aliases ?? StringUtils.EmptyStringsList;
/// <summary>
/// Checks wether a givin candidate name has a defined object or alias
@@ -139,10 +120,8 @@ namespace Spring.Objects.Factory.Config
/// <returns></returns>
public bool MatchesName(string candidateName)
{
return (!string.IsNullOrEmpty(candidateName) &&
(candidateName.Equals(ObjectName) || Aliases.Contains(candidateName)));
return !string.IsNullOrEmpty(candidateName)
&& (candidateName == ObjectName || aliases?.Contains(candidateName) == true);
}
#endregion
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -240,7 +240,7 @@ namespace Spring.Objects.Factory.Config
PlaceholderResolveHandlerAdapter resolveAdapter = new PlaceholderResolveHandlerAdapter(this, props);
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(resolveAdapter.ParseAndResolveVariables);
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames(includeAncestors);
var objectDefinitionNames = factory.GetObjectDefinitionNames(includeAncestors);
for (int i = 0; i < objectDefinitionNames.Count; ++i)
{
string name = objectDefinitionNames[i];

View File

@@ -1,5 +1,3 @@
#region License
/*
* Copyright 2002-2010 the original author or authors.
*
@@ -16,8 +14,6 @@
* limitations under the License.
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
@@ -75,8 +71,6 @@ namespace Spring.Objects.Factory.Config
/// </summary>
public static readonly string DefaultPlaceholderSuffix = "}";
#region Fields
private int order = Int32.MaxValue; // default: same as non-Ordered
private bool includeAncestors;
@@ -86,8 +80,6 @@ namespace Spring.Objects.Factory.Config
private IList variableSourceList = new ArrayList();
#endregion
/// <summary>
/// Create a new instance without any variable sources
/// </summary>
@@ -111,8 +103,6 @@ namespace Spring.Objects.Factory.Config
this.VariableSources = variableSources;
}
#region Properties
/// <summary>
/// Sets the list of <see cref="IVariableSource"/>s that will be used to resolve placeholder names.
/// </summary>
@@ -166,10 +156,6 @@ namespace Spring.Objects.Factory.Config
set { includeAncestors = value; }
}
#endregion
#region IObjectFactoryPostProcessor Members
/// <summary>
/// Modify the application context's internal object factory after its
/// standard initialization.
@@ -216,10 +202,6 @@ namespace Spring.Objects.Factory.Config
}
}
#endregion
#region IOrdered Members
/// <summary>
/// Return the order value of this object, where a higher value means greater in
/// terms of sorting.
@@ -232,8 +214,6 @@ namespace Spring.Objects.Factory.Config
set { order = value; }
}
#endregion
/// <summary>
/// Apply the property replacement using the specified <see cref="IVariableSource"/>s for all
/// object in the supplied
@@ -252,7 +232,7 @@ namespace Spring.Objects.Factory.Config
TextProcessor tp = new TextProcessor(this, compositeVariableSource);
ObjectDefinitionVisitor visitor = new ObjectDefinitionVisitor(new ObjectDefinitionVisitor.ResolveHandler(tp.ParseAndResolveVariables));
IList<string> objectDefinitionNames = factory.GetObjectDefinitionNames(includeAncestors);
var objectDefinitionNames = factory.GetObjectDefinitionNames(includeAncestors);
for (int i = 0; i < objectDefinitionNames.Count; ++i)
{
string name = objectDefinitionNames[i];
@@ -273,8 +253,6 @@ namespace Spring.Objects.Factory.Config
}
}
#region Helper class
private class TextProcessor
{
private readonly ILog logger = LogManager.GetLogger(typeof(TextProcessor));
@@ -323,8 +301,6 @@ namespace Spring.Objects.Factory.Config
string resolvedValue = variableSource.ResolveVariable(placeholder);
resolvedValue = ParseAndResolveVariables(resolvedValue, visitedPlaceholders);
#region Instrumentation
if (logger.IsDebugEnabled)
{
logger.Debug(string.Format(
@@ -332,8 +308,6 @@ namespace Spring.Objects.Factory.Config
"Resolving placeholder '{0}' to '{1}'.", placeholder, resolvedValue));
}
#endregion
if (resolvedValue == null
&& startIndex == 0
&& strVal.Length <= endIndex + owner.placeholderSuffix.Length)
@@ -395,7 +369,5 @@ namespace Spring.Objects.Factory.Config
return false;
}
}
#endregion
}
}

View File

@@ -93,7 +93,7 @@ namespace Spring.Objects.Factory
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
IList<string> GetObjectDefinitionNames();
IReadOnlyList<string> GetObjectDefinitionNames();
/// <summary>
/// Return the names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code>
@@ -104,7 +104,7 @@ namespace Spring.Objects.Factory
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
IList<string> GetObjectDefinitionNames(bool includeAncestors);
IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestors);
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
@@ -129,7 +129,7 @@ namespace Spring.Objects.Factory
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
IList<string> GetObjectNamesForType(Type type);
IReadOnlyList<string> GetObjectNamesForType(Type type);
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
@@ -154,8 +154,7 @@ namespace Spring.Objects.Factory
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
IList<string> GetObjectNames<T>();
IReadOnlyList<string> GetObjectNames<T>();
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
@@ -192,44 +191,44 @@ namespace Spring.Objects.Factory
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
IList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects);
IReadOnlyList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects);
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
/// (including subclasses), judging from the object definitions.
/// </summary>
/// <remarks>
/// <p>
/// Does consider objects created by <see cref="Spring.Objects.Factory.IFactoryObject"/>s,
/// or rather it considers the type of objects created by
/// <see cref="Spring.Objects.Factory.IFactoryObject"/> (which means that
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s will be instantiated).
/// </p>
/// <p>
/// Does not consider any hierarchy this factory may participate in.
/// Use <see cref="ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(Spring.Objects.Factory.IListableObjectFactory,System.Type,bool,bool)"/>
/// to include beans in ancestor factories too.
/// &lt;p&gt;Note: Does &lt;i&gt;not&lt;/i&gt; ignore singleton objects that have been registered
/// by other means than bean definitions.
/// </p>
/// </remarks>
/// <typeparam name="T">
/// The <see cref="System.Type"/> (class or interface) to match, or <see langword="null"/>
/// for all object names.
/// </typeparam>
/// <param name="includePrototypes">
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// </param>
/// <param name="includeFactoryObjects">
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// </param>
/// <returns>
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
IList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects);
/// <summary>
/// Return the names of objects matching the given <see cref="System.Type"/>
/// (including subclasses), judging from the object definitions.
/// </summary>
/// <remarks>
/// <p>
/// Does consider objects created by <see cref="Spring.Objects.Factory.IFactoryObject"/>s,
/// or rather it considers the type of objects created by
/// <see cref="Spring.Objects.Factory.IFactoryObject"/> (which means that
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s will be instantiated).
/// </p>
/// <p>
/// Does not consider any hierarchy this factory may participate in.
/// Use <see cref="ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(Spring.Objects.Factory.IListableObjectFactory,System.Type,bool,bool)"/>
/// to include beans in ancestor factories too.
/// &lt;p&gt;Note: Does &lt;i&gt;not&lt;/i&gt; ignore singleton objects that have been registered
/// by other means than bean definitions.
/// </p>
/// </remarks>
/// <typeparam name="T">
/// The <see cref="System.Type"/> (class or interface) to match, or <see langword="null"/>
/// for all object names.
/// </typeparam>
/// <param name="includePrototypes">
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// </param>
/// <param name="includeFactoryObjects">
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// </param>
/// <returns>
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
IReadOnlyList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects);
/// <summary>
/// Return the object instances that match the given object
@@ -258,7 +257,7 @@ namespace Spring.Objects.Factory
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
IDictionary<string, object> GetObjectsOfType(Type type);
IReadOnlyDictionary<string, object> GetObjectsOfType(Type type);
/// <summary>
/// Return the object instances that match the given object
@@ -287,7 +286,7 @@ namespace Spring.Objects.Factory
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
IDictionary<string, T> GetObjects<T>();
IReadOnlyDictionary<string, T> GetObjects<T>();
/// <summary>
/// Return the object instances that match the given object
@@ -315,7 +314,7 @@ namespace Spring.Objects.Factory
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
IDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects);
IReadOnlyDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects);
/// <summary>
/// Return the object instances that match the given object
@@ -343,6 +342,6 @@ namespace Spring.Objects.Factory
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
IDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects);
IReadOnlyDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects);
}
}

View File

@@ -210,21 +210,21 @@ namespace Spring.Objects.Factory
/// <returns>True if an object with the given name is defined.</returns>
bool ContainsObject(string name);
/// <summary>
/// Return the aliases for the given object name, if defined.
/// </summary>
/// <remarks>
/// <para>
/// Will ask the parent factory if the object cannot be found in this factory
/// instance.
/// </para>
/// </remarks>
/// <param name="name">The object name to check for aliases.</param>
/// <returns>The aliases, or an empty array if none.</returns>
/// <exception cref="Spring.Objects.Factory.NoSuchObjectDefinitionException">
/// If there's no such object definition.
/// </exception>
IList<string> GetAliases(string name);
/// <summary>
/// Return the aliases for the given object name, if defined.
/// </summary>
/// <remarks>
/// <para>
/// Will ask the parent factory if the object cannot be found in this factory
/// instance.
/// </para>
/// </remarks>
/// <param name="name">The object name to check for aliases.</param>
/// <returns>The aliases, or an empty array if none.</returns>
/// <exception cref="Spring.Objects.Factory.NoSuchObjectDefinitionException">
/// If there's no such object definition.
/// </exception>
IReadOnlyList<string> GetAliases(string name);
#if !MONO
/// <summary>

View File

@@ -115,7 +115,7 @@ namespace Spring.Objects.Factory
/// </summary>
/// <param name="factory">The object factory.</param>
/// <returns>The array of object names, or an empty array if none.</returns>
public static IList<string> ObjectNamesIncludingAncestors(IListableObjectFactory factory)
public static IReadOnlyList<string> ObjectNamesIncludingAncestors(IListableObjectFactory factory)
{
return ObjectNamesForTypeIncludingAncestors(factory, typeof(object));
}
@@ -155,7 +155,7 @@ namespace Spring.Objects.Factory
/// <returns>
/// The array of object names, or an empty array if none.
/// </returns>
public static IList<string> ObjectNamesForTypeIncludingAncestors(
public static List<string> ObjectNamesForTypeIncludingAncestors(
IListableObjectFactory factory, Type type,
bool includePrototypes, bool includeFactoryObjects)
{
@@ -202,7 +202,7 @@ namespace Spring.Objects.Factory
/// <returns>
/// The array of object names, or an empty array if none.
/// </returns>
public static IList<string> ObjectNamesForTypeIncludingAncestors(IListableObjectFactory factory, Type type)
public static IReadOnlyList<string> ObjectNamesForTypeIncludingAncestors(IListableObjectFactory factory, Type type)
{
return factory.GetObjectNamesForType(type);
}
@@ -235,21 +235,21 @@ namespace Spring.Objects.Factory
/// The <see cref="System.Collections.IDictionary"/> of object instances, or an
/// empty <see cref="System.Collections.IDictionary"/> if none.
/// </returns>
public static IDictionary<string, object> ObjectsOfTypeIncludingAncestors(
public static Dictionary<string, object> ObjectsOfTypeIncludingAncestors(
IListableObjectFactory factory, Type type,
bool includePrototypes, bool includeFactoryObjects)
{
Dictionary<string, object> result = new Dictionary<string, object>();
foreach (KeyValuePair<string, object> entry in
factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects))
foreach (var entry in factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects))
{
result.Add(entry.Key, entry.Value);
}
IListableObjectFactory pof = GetParentListableObjectFactoryIfAny(factory);
if (pof != null)
{
IHierarchicalObjectFactory hof = (IHierarchicalObjectFactory)factory;
IDictionary<string, object> parentResult = ObjectsOfTypeIncludingAncestors(pof, type, includePrototypes, includeFactoryObjects);
Dictionary<string, object> parentResult = ObjectsOfTypeIncludingAncestors(pof, type, includePrototypes, includeFactoryObjects);
foreach (string objectName in parentResult.Keys)
{
if (!result.ContainsKey(objectName) && !hof.ContainsLocalObject(objectName))
@@ -295,7 +295,7 @@ namespace Spring.Objects.Factory
IListableObjectFactory factory, Type type,
bool includePrototypes, bool includeFactoryObjects)
{
IDictionary<string, object> objectsOfType = ObjectsOfTypeIncludingAncestors(factory, type, includePrototypes, includeFactoryObjects);
var objectsOfType = ObjectsOfTypeIncludingAncestors(factory, type, includePrototypes, includeFactoryObjects);
return GrabTheOnlyObject(objectsOfType, type);
}
@@ -331,7 +331,7 @@ namespace Spring.Objects.Factory
public static object ObjectOfType(IListableObjectFactory factory, Type type,
bool includePrototypes, bool includeFactoryObjects)
{
IDictionary<string, object> objectsOfType = factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects);
var objectsOfType = factory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects);
return GrabTheOnlyObject(objectsOfType, type);
}
@@ -433,7 +433,7 @@ namespace Spring.Objects.Factory
return null;
}
private static object GrabTheOnlyObject(IDictionary<string, object> objectsOfType, Type type)
private static object GrabTheOnlyObject(IReadOnlyDictionary<string, object> objectsOfType, Type type)
{
if (objectsOfType.Count == 1)
{

View File

@@ -56,6 +56,24 @@ namespace Spring.Objects.Factory.Support
[Serializable]
public abstract class AbstractAutowireCapableObjectFactory : AbstractObjectFactory, IAutowireCapableObjectFactory
{
private IInstantiationStrategy instantiationStrategy = new MethodInjectingInstantiationStrategy();
/// <summary>
/// Cache of filtered PropertyInfos: object Type -> PropertyInfo array
/// </summary>
private readonly ConcurrentDictionary<Type, List<PropertyInfo>> filteredPropertyDescriptorsCache = new ConcurrentDictionary<Type, List<PropertyInfo>>();
/// <summary>
/// Dependency interfaces to ignore on dependency check and autowire, as Set of
/// Class objects. By default, only the IObjectFactoryAware and IObjectNameAware
/// interfaces are ignored.
/// </summary>
private readonly HybridSet ignoredDependencyInterfaces = new HybridSet();
[NonSerialized]
private ObjectDefinitionValueResolver cachedValueResolver;
/// <summary>
/// The <see cref="System.Reflection.BindingFlags"/> used during the invocation and
/// searching for of methods.
@@ -226,7 +244,7 @@ namespace Spring.Objects.Factory.Support
RootObjectDefinition definition = GetMergedObjectDefinition(name, true);
if (definition != null)
{
log.Debug(string.Format("configuring object '{0}' using definition '{1}'", instance, name));
log.Debug($"configuring object '{instance}' using definition '{name}'");
ApplyPropertyValues(name, definition, new ObjectWrapper(instance), definition.PropertyValues);
}
}
@@ -248,6 +266,7 @@ namespace Spring.Objects.Factory.Support
/// </param>
public override void ApplyObjectPropertyValues(object instance, string name, IObjectDefinition definition)
{
MarkObjectAsCreated(name);
ApplyPropertyValues(name, new RootObjectDefinition(definition), new ObjectWrapper(instance), definition.PropertyValues);
}
@@ -389,7 +408,7 @@ namespace Spring.Objects.Factory.Support
/// </summary>
protected virtual ObjectDefinitionValueResolver CreateValueResolver()
{
return new ObjectDefinitionValueResolver(this);
return cachedValueResolver ?? (cachedValueResolver =new ObjectDefinitionValueResolver(this));
}
/// <summary>
@@ -481,7 +500,7 @@ namespace Spring.Objects.Factory.Support
// to support styles of field injection.
bool continueWithPropertyPopulation = true;
if (HasInstantiationAwareBeanPostProcessors)
if (HasInstantiationAwareObjectPostProcessors)
{
for (var i = 0; i < ObjectPostProcessors.Count; i++)
{
@@ -533,7 +552,7 @@ namespace Spring.Objects.Factory.Support
//DependencyCheck(name, definition, wrapper, properties);
bool hasInstAwareOpps = HasInstantiationAwareBeanPostProcessors;
bool hasInstAwareOpps = HasInstantiationAwareObjectPostProcessors;
bool needsDepCheck = (definition.DependencyCheck != DependencyCheckingMode.None);
if (hasInstAwareOpps || needsDepCheck)
@@ -1020,7 +1039,7 @@ namespace Spring.Objects.Factory.Support
/// <seealso cref="SmartInstantiationAwareObjectPostProcessor.DetermineCandidateConstructors"/>
protected virtual ConstructorInfo[] DetermineConstructorsFromObjectPostProcessors(Type objectType, string objectName)
{
if (HasInstantiationAwareBeanPostProcessors)
if (HasInstantiationAwareObjectPostProcessors)
{
for (var i = 0; i < ObjectPostProcessors.Count; i++)
{
@@ -1142,7 +1161,7 @@ namespace Spring.Objects.Factory.Support
}
IList<PropertyInfo> filteredPropInfo = FilterPropertyInfoForDependencyCheck(wrapper);
if (HasInstantiationAwareBeanPostProcessors)
if (HasInstantiationAwareObjectPostProcessors)
{
for (var i = 0; i < ObjectPostProcessors.Count; i++)
{
@@ -1699,6 +1718,7 @@ namespace Spring.Objects.Factory.Support
/// <seealso cref="Spring.Objects.Factory.IObjectFactory.ConfigureObject(object, string)"/>
public override object ConfigureObject(object target, string name)
{
MarkObjectAsCreated(name);
RootObjectDefinition definition = GetMergedObjectDefinition(name, true);
if (definition != null)
{
@@ -1964,20 +1984,6 @@ namespace Spring.Objects.Factory.Support
DependencyDescriptor descriptor,
string objectName,
IList<string> autowiredObjectNames);
private IInstantiationStrategy instantiationStrategy = new MethodInjectingInstantiationStrategy();
/// <summary>
/// Cache of filtered PropertyInfos: object Type -> PropertyInfo array
/// </summary>
private readonly ConcurrentDictionary<Type, List<PropertyInfo>> filteredPropertyDescriptorsCache = new ConcurrentDictionary<Type, List<PropertyInfo>>();
/// <summary>
/// Dependency interfaces to ignore on dependency check and autowire, as Set of
/// Class objects. By default, only the IObjectFactoryAware and IObjectNameAware
/// interfaces are ignored.
/// </summary>
private readonly HybridSet ignoredDependencyInterfaces = new HybridSet();
}
internal class UnsatisfiedDependencyExceptionData

View File

@@ -24,7 +24,6 @@ using System.ComponentModel;
using Common.Logging;
using Spring.Collections;
using Spring.Collections.Generic;
using Spring.Core;
using Spring.Core.TypeConversion;
using Spring.Objects.Factory.Config;
@@ -53,59 +52,6 @@ namespace Spring.Objects.Factory.Support
[Serializable]
public abstract class AbstractObjectFactory : IConfigurableObjectFactory
{
[Serializable]
private class LogicalThreadContextSetVariable : IDisposable
{
private readonly string name = Guid.NewGuid().ToString();
public HashSet<string> Value
{
get
{
if (!(LogicalThreadContext.GetData(name) is HashSet<string> set))
{
set = new HashSet<string>();
LogicalThreadContext.SetData(name, set);
}
return set;
}
}
public void Dispose()
{
LogicalThreadContext.FreeNamedDataSlot(name);
}
}
/// <summary>
/// Makes a distinction between sort order and object identity.
/// This is important when used with <see cref="ISet"/>, since most
/// implementations assume Order == Identity
/// </summary>
[Serializable]
private class ObjectOrderComparator : OrderComparator
{
/// <summary>
/// Handle the case when both objects have equal sort order priority. By default returns 0,
/// but may be overriden for handling special cases.
/// </summary>
/// <param name="o1">The first object to compare.</param>
/// <param name="o2">The second object to compare.</param>
/// <returns>
/// -1 if first object is less then second, 1 if it is greater, or 0 if they are equal.
/// </returns>
protected override int CompareEqualOrder(object o1, object o2)
{
if (ReferenceEquals(o1, o2))
return 0;
if (o1 == null)
return 1;
if (o2 == null)
return -1;
return o1.GetHashCode().CompareTo(o2.GetHashCode());
}
}
/// <summary>
/// Marker object to be temporarily registered in the singleton cache,
/// while instantiating an object (in order to be able to detect circular references).
@@ -147,7 +93,7 @@ namespace Spring.Objects.Factory.Support
/// <summary>
/// Names of object that have already been created at least once
/// </summary>
private Collections.Generic.ISet<string> alreadyCreated = new SynchronizedSet<string>(new HashedSet<string>());
private readonly HashSet<string> alreadyCreated = new HashSet<string>();
/// <summary>
/// Creates a new instance of the
@@ -165,7 +111,8 @@ namespace Spring.Objects.Factory.Support
/// </remarks>
protected AbstractObjectFactory()
: this(true)
{ }
{
}
/// <summary>
/// Creates a new instance of the
@@ -247,12 +194,18 @@ namespace Spring.Objects.Factory.Support
/// <summary>
/// Returns, whether this object factory instance contains <see cref="IInstantiationAwareObjectPostProcessor"/> objects.
/// </summary>
protected bool HasInstantiationAwareBeanPostProcessors => hasInstantiationAwareBeanPostProcessors;
protected bool HasInstantiationAwareObjectPostProcessors => hasInstantiationAwareObjectPostProcessors;
/// <summary>
/// Returns, whether this object factory instance contains <see cref="IDestructionAwareObjectPostProcessor"/> objects.
/// </summary>
protected bool HasDestructionAwareBeanPostProcessors => hasDestructionAwareBeanPostProcessors;
protected bool HasDestructionAwareObjectPostProcessors => hasDestructionAwareObjectPostProcessors;
/// <summary>
/// Check whether this factory's bean creation phase already started,
/// i.e. whether any bean has been marked as created in the meantime.
/// </summary>
protected bool HasObjectCreationStarted => alreadyCreated.Count > 0;
/// <summary>
/// Return an instance (possibly shared or independent) of the given object name.
@@ -690,14 +643,7 @@ namespace Spring.Objects.Factory.Support
/// </returns>
protected RootObjectDefinition GetMergedLocalObjectDefinition(string objectName)
{
// Quick check on the concurrent map first, with minimal locking.
RootObjectDefinition mbd = null;
if (mergedObjectDefinitions.ContainsKey(objectName))
{
mbd = mergedObjectDefinitions[objectName] as RootObjectDefinition;
}
mergedObjectDefinitions.TryGetValue(objectName, out var mbd);
return mbd; // ?? GetMergedObjectDefinition(objectName, GetObjectDefinition(objectName));
}
@@ -708,7 +654,7 @@ namespace Spring.Objects.Factory.Support
/// <returns>
/// <c>true</c> if [is object eligible for metadata caching] [the specified bean name]; otherwise, <c>false</c>.
/// </returns>
protected bool IsObjectEligibleForMetadataCaching(string beanName)
protected virtual bool IsObjectEligibleForMetadataCaching(string beanName)
{
return alreadyCreated.Contains(beanName);
}
@@ -835,6 +781,45 @@ namespace Spring.Objects.Factory.Support
return null;
}
}
/// <summary>
/// Mark the specified bean as already created (or about to be created).
/// </summary>
/// <remarks>
/// This allows the bean factory to optimize its caching for repeated
/// creation of the specified bean.
/// </remarks>
/// <param name="objectName">The name of the object.</param>
protected void MarkObjectAsCreated(string objectName)
{
if (alreadyCreated.Contains(objectName))
{
return;
}
lock (mergedObjectDefinitions)
{
if (!alreadyCreated.Contains(objectName))
{
// Let the bean definition get re-merged now that we're actually creating
// the object... just in case some of its metadata changed in the meantime.
ClearMergedObjectDefinition(objectName);
alreadyCreated.Add(objectName);
}
}
}
/// <summary>
/// Perform appropriate cleanup of cached metadata after bean creation failed.
/// </summary>
/// <param name="objectName">The name of the object</param>
protected void CleanupAfterObjectCreationFailure(string objectName)
{
lock (mergedObjectDefinitions)
{
alreadyCreated.Remove(objectName);
}
}
/// <summary>
/// Predict the eventual object type (of the processed object instance) for the
@@ -1581,6 +1566,37 @@ namespace Spring.Objects.Factory.Support
*/
}
}
/// <summary>
/// Remove the merged bean definition for the specified bean,
/// recreating it on next access.
/// </summary>
/// <param name="objectName">The bean name to clear the merged definition for</param>
protected void ClearMergedObjectDefinition(string objectName)
{
mergedObjectDefinitions.TryRemove(objectName, out _);
}
/// <summary>
/// Clear the merged object definition cache, removing entries for objects
/// which are not considered eligible for full metadata caching yet.
/// </summary>
/// <remarks>
/// Typically triggered after changes to the original object definitions,
/// e.g. after applying a <see cref="IObjectFactoryPostProcessor" />. Note that metadata
/// for objects which have already been created at this point will be kept around.
/// </remarks>
public virtual void ClearMetadataCache()
{
var keys = new List<string>(mergedObjectDefinitions.Keys);
foreach (var key in keys)
{
if (!IsObjectEligibleForMetadataCaching(key))
{
mergedObjectDefinitions.TryRemove(key, out _);
}
}
}
/// <summary>
/// Gets the temporary object that is placed
@@ -1607,17 +1623,17 @@ namespace Spring.Objects.Factory.Support
/// <summary>
/// String Resolver applied to Autowired value injections
/// </summary>
private SortedSet embeddedValueResolvers = new SortedSet(new ObjectOrderComparator());
private SortedSet embeddedValueResolvers = new SortedSet(ObjectOrderComparator.ObjectOrderComparatorInstance);
/// <summary>
/// Indicates whether any IInstantiationAwareBeanPostProcessors have been registered
/// </summary>
private bool hasInstantiationAwareBeanPostProcessors;
private bool hasInstantiationAwareObjectPostProcessors;
/// <summary>
/// Indicates whether any IDestructionAwareBeanPostProcessors have been registered
/// </summary>
private bool hasDestructionAwareBeanPostProcessors;
private bool hasDestructionAwareObjectPostProcessors;
private bool caseSensitive;
private OrderedDictionary aliasMap;
@@ -1807,7 +1823,12 @@ namespace Spring.Objects.Factory.Support
/// Return the aliases for the given object name, if defined.
/// </summary>
/// <see cref="Spring.Objects.Factory.IObjectFactory.GetAliases"/>.
public IList<string> GetAliases(string name)
public IReadOnlyList<string> GetAliases(string name)
{
return DoGetAliases(name);
}
internal List<string> DoGetAliases(string name)
{
string objectName = TransformedObjectName(name);
// check if object actually exists in this object factory...
@@ -1830,8 +1851,9 @@ namespace Spring.Objects.Factory.Support
// not found, so check parent...
if (ParentObjectFactory != null)
{
return ParentObjectFactory.GetAliases(objectName);
return new List<string>(ParentObjectFactory.GetAliases(objectName));
}
throw new NoSuchObjectDefinitionException(objectName, ToString());
}
@@ -2077,7 +2099,7 @@ namespace Spring.Objects.Factory.Support
protected object GetObjectInternal(string name, Type requiredType, object[] arguments, bool suppressConfigure)
{
object monitor = new object();
const int INDENT = 3;
const int indent = 3;
bool hasErrors = false;
try
{
@@ -2086,7 +2108,7 @@ namespace Spring.Objects.Factory.Support
if (log.IsDebugEnabled)
{
log.Debug(string.Format("{2}GetObjectInternal: obtaining instance for name {0} => canonical name {1}", name, objectName, new string(' ', nestingCount * INDENT)));
log.Debug(string.Format("{2}GetObjectInternal: obtaining instance for name {0} => canonical name {1}", name, objectName, new string(' ', nestingCount * indent)));
}
object instance = null;
@@ -2121,9 +2143,13 @@ namespace Spring.Objects.Factory.Support
throw new ObjectCurrentlyInCreationException(name);
}
if (!suppressConfigure)
{
MarkObjectAsCreated(objectName);
}
// check if object definition exists
RootObjectDefinition mergedObjectDefinition = null;
mergedObjectDefinition = GetMergedObjectDefinition(objectName, false);
var mergedObjectDefinition = GetMergedObjectDefinition(objectName, false);
if (mergedObjectDefinition == null)
{
if (ParentObjectFactory != null)
@@ -2133,8 +2159,7 @@ namespace Spring.Objects.Factory.Support
throw new NoSuchObjectDefinitionException(name, "Cannot find definition for object [" + name + "]");
}
if (arguments != null
|| suppressConfigure)
if (arguments != null || suppressConfigure)
{
// Clone ObjectDefinition
mergedObjectDefinition = CreateRootObjectDefinition(mergedObjectDefinition);
@@ -2186,7 +2211,6 @@ namespace Spring.Objects.Factory.Support
}
catch
{
lock (monitor)
{
if (nestingCount > 0)
@@ -2195,10 +2219,12 @@ namespace Spring.Objects.Factory.Support
}
}
CleanupAfterObjectCreationFailure(name);
hasErrors = true;
if (log.IsErrorEnabled)
{
log.Error(string.Format("{1}GetObjectInternal: error obtaining object {0}", name, new string(' ', nestingCount * INDENT)));
log.Error(string.Format("{1}GetObjectInternal: error obtaining object {0}", name, new string(' ', nestingCount * indent)));
}
throw;
@@ -2217,7 +2243,7 @@ namespace Spring.Objects.Factory.Support
if (log.IsDebugEnabled)
{
log.Debug(string.Format("{1}GetObjectInternal: returning instance for objectname {0}", name, new string(' ', nestingCount * INDENT)));
log.Debug(string.Format("{1}GetObjectInternal: returning instance for objectname {0}", name, new string(' ', nestingCount * indent)));
}
}
}
@@ -2248,7 +2274,7 @@ namespace Spring.Objects.Factory.Support
protected bool RequiresDestruction(object instance, RootObjectDefinition od)
{
return (instance != null &&
(instance is IDisposable || od.DestroyMethodName != null || HasDestructionAwareBeanPostProcessors));
(instance is IDisposable || od.DestroyMethodName != null || HasDestructionAwareObjectPostProcessors));
}
private int nestingCount;
@@ -2390,12 +2416,10 @@ namespace Spring.Objects.Factory.Support
private void AfterPrototypeCreation(string name)
{
var values = prototypesInCreation.Value;
if (!values.Contains(name))
if (!prototypesInCreation.Value.Remove(name))
{
ThrowNotCurrentlyInCreation(name);
}
values.Remove(name);
}
private static void ThrowNotCurrentlyInCreation(string name)
@@ -2478,11 +2502,11 @@ namespace Spring.Objects.Factory.Support
}
if (typeof(IInstantiationAwareObjectPostProcessor).IsInstanceOfType(objectPostProcessor))
{
hasInstantiationAwareBeanPostProcessors = true;
hasInstantiationAwareObjectPostProcessors = true;
}
if (typeof(IDestructionAwareObjectPostProcessor).IsInstanceOfType(objectPostProcessor))
{
hasDestructionAwareBeanPostProcessors = true;
hasDestructionAwareObjectPostProcessors = true;
}
}
@@ -2548,7 +2572,7 @@ namespace Spring.Objects.Factory.Support
/// under the given object name.
/// </summary>
/// <seealso cref="Spring.Objects.Factory.Config.ISingletonObjectRegistry.RegisterSingleton"/>.
public void RegisterSingleton(string name, object singletonObject)
public virtual void RegisterSingleton(string name, object singletonObject)
{
AssertUtils.ArgumentHasText(name, "name", "The singleton object cannot be registered under an empty name.");
lock (GetSingletonLockFor(name))
@@ -2557,9 +2581,7 @@ namespace Spring.Objects.Factory.Support
if (oldObject != null)
{
throw new ObjectDefinitionStoreException(
string.Format(
"Could not register object [{0}] under object name '{1}': there's already object [{2}] bound.",
singletonObject, name, oldObject));
$"Could not register object [{singletonObject}] under object name '{name}': there's already object [{oldObject}] bound.");
}
AddSingleton(name, singletonObject);
}
@@ -2694,5 +2716,59 @@ namespace Spring.Objects.Factory.Support
{
return singletonLocks.GetOrAdd(objectName, key => new Lazy<object>(() => new object())).Value;
}
[Serializable]
private class LogicalThreadContextSetVariable : IDisposable
{
private readonly string name = Guid.NewGuid().ToString();
public HashSet<string> Value
{
get
{
if (!(LogicalThreadContext.GetData(name) is HashSet<string> set))
{
set = new HashSet<string>();
LogicalThreadContext.SetData(name, set);
}
return set;
}
}
public void Dispose()
{
LogicalThreadContext.FreeNamedDataSlot(name);
}
}
/// <summary>
/// Makes a distinction between sort order and object identity.
/// This is important when used with <see cref="ISet"/>, since most
/// implementations assume Order == Identity
/// </summary>
[Serializable]
private class ObjectOrderComparator : OrderComparator
{
public static readonly ObjectOrderComparator ObjectOrderComparatorInstance = new ObjectOrderComparator();
/// <summary>
/// Handle the case when both objects have equal sort order priority. By default returns 0,
/// but may be overriden for handling special cases.
/// </summary>
/// <param name="o1">The first object to compare.</param>
/// <param name="o2">The second object to compare.</param>
/// <returns>
/// -1 if first object is less then second, 1 if it is greater, or 0 if they are equal.
/// </returns>
protected override int CompareEqualOrder(object o1, object o2)
{
if (ReferenceEquals(o1, o2))
return 0;
if (o1 == null)
return 1;
if (o2 == null)
return -1;
return o1.GetHashCode().CompareTo(o2.GetHashCode());
}
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -82,7 +82,7 @@ namespace Spring.Objects.Factory.Support
MemberInfo[] ctors = definition.ObjectType.FindMembers(
MemberTypes.Constructor,
flags,
new MemberFilter(new CriteriaMemberFilter().FilterMemberByCriteria),
new CriteriaMemberFilter().FilterMemberByCriteria,
new MinimumArgumentCountCriteria(minimumArgumentCount));
constructors = (ConstructorInfo[]) ArrayList.Adapter(ctors).ToArray(typeof (ConstructorInfo));
}
@@ -90,7 +90,7 @@ namespace Spring.Objects.Factory.Support
{
constructors = definition.ObjectType.GetConstructors(flags);
}
AutowireUtils.SortConstructors(constructors);
SortConstructors(constructors);
return constructors;
}
@@ -181,11 +181,11 @@ namespace Spring.Objects.Factory.Support
public static int GetTypeDifferenceWeight(Type[] paramTypes, object[] args)
{
int result = 0;
for (int i = 0; i < paramTypes.Length; i++)
for (int i = 0; i < (uint) paramTypes.Length; i++)
{
if (!ObjectUtils.IsAssignable(paramTypes[i], args[i]))
{
return Int32.MaxValue;
return int.MaxValue;
}
if (args[i] != null)
{
@@ -193,7 +193,7 @@ namespace Spring.Objects.Factory.Support
Type superType = args[i].GetType().BaseType;
while (superType != null)
{
if (paramType.Equals(superType))
if (paramType == superType)
{
result = result + 2;
superType = null;
@@ -226,7 +226,7 @@ namespace Spring.Objects.Factory.Support
/// </returns>
public static Boolean IsExcludedFromDependencyCheck(PropertyInfo pi)
{
return (pi.GetSetMethod() == null) ? false : true;
return pi.GetSetMethod() != null;
}
/// <summary>
@@ -245,15 +245,16 @@ namespace Spring.Objects.Factory.Support
/// </param>
public static void SortConstructors(ConstructorInfo[] constructors)
{
if (constructors != null
&& constructors.Length > 0)
if (constructors != null && constructors.Length > 0)
{
Array.Sort(constructors, new ConstructorComparer());
Array.Sort(constructors, ConstructorComparer.Instance);
}
}
private sealed class ConstructorComparer : IComparer
{
{
internal static readonly ConstructorComparer Instance = new ConstructorComparer();
public int Compare(object lhs, object rhs)
{
ConstructorInfo lhsCtor = (ConstructorInfo) lhs;
@@ -282,6 +283,8 @@ namespace Spring.Objects.Factory.Support
private sealed class MinimumArgumentCountCriteria : ICriteria
{
private readonly int _minimumArgumentCount;
public MinimumArgumentCountCriteria(int minimumArgumentCount)
{
_minimumArgumentCount = minimumArgumentCount;
@@ -289,12 +292,8 @@ namespace Spring.Objects.Factory.Support
public bool IsSatisfied(object datum)
{
bool satisfied = false;
satisfied = ((MethodBase) datum).GetParameters().Length >= _minimumArgumentCount;
return satisfied;
return ((MethodBase) datum).GetParameters().Length >= _minimumArgumentCount;
}
private int _minimumArgumentCount;
}
/// <summary>

View File

@@ -114,8 +114,11 @@ namespace Spring.Objects.Factory.Support
/// <param name="explicitArgs">The explicit chose ctor args.</param>
/// <returns>A ConstructorInstantiationInfo containg the specified constructor in the RootObjectDefinition or
/// one based on type matching.</returns>
public ConstructorInstantiationInfo GetConstructorInstantiationInfo(string objectName, RootObjectDefinition rod,
ConstructorInfo[] chosenCtors, object[] explicitArgs)
public ConstructorInstantiationInfo GetConstructorInstantiationInfo(
string objectName,
RootObjectDefinition rod,
ConstructorInfo[] chosenCtors,
object[] explicitArgs)
{
ObjectWrapper wrapper = new ObjectWrapper();
@@ -150,11 +153,9 @@ namespace Spring.Objects.Factory.Support
minNrOfArgs = ResolveConstructorArguments(objectName, rod, wrapper, cargs, resolvedValues);
}
// Take specified constructors, if any.
ConstructorInfo[] candidates = (chosenCtors != null
? chosenCtors
: AutowireUtils.GetConstructors(rod, 0));
ConstructorInfo[] candidates = chosenCtors ?? AutowireUtils.GetConstructors(rod, 0);
AutowireUtils.SortConstructors(candidates);
int minTypeDiffWeight = Int32.MaxValue;
int minTypeDiffWeight = int.MaxValue;
for (int i = 0; i < candidates.Length; i++)
{
@@ -174,17 +175,24 @@ namespace Spring.Objects.Factory.Support
+ "in object '{1}' (hint: specify argument indexes, names, or "
+ "types to avoid ambiguities).", minNrOfArgs, objectName));
}
ArgumentsHolder args = null;
ArgumentsHolder args;
if (resolvedValues != null)
{
UnsatisfiedDependencyExceptionData unsatisfiedDependencyExceptionData = null;
// Try to resolve arguments for current constructor
//need to check for null as indicator of no ctor arg match instead of using exceptions for flow
//control as in the Java implementation
args = CreateArgumentArray(objectName, rod, resolvedValues, wrapper, paramTypes, candidate,
autowiring, out unsatisfiedDependencyExceptionData);
args = CreateArgumentArray(
objectName,
rod,
resolvedValues,
wrapper,
paramTypes,
candidate,
autowiring,
out var unsatisfiedDependencyExceptionData);
if (args == null)
{
if (i == candidates.Length - 1 && constructorToUse == null)

View File

@@ -16,14 +16,15 @@
using System;
using System.Collections;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Globalization;
using Spring.Collections.Generic;
using Spring.Core;
using Spring.Core.TypeConversion;
using Spring.Expressions;
using Spring.Objects.Factory.Config;
using Spring.Util;
using Spring.Expressions;
namespace Spring.Objects.Factory.Support
{
@@ -62,6 +63,37 @@ namespace Spring.Objects.Factory.Support
IConfigurableListableObjectFactory,
IObjectDefinitionRegistry
{
// The mapping of object depending object names, keyed by object name.
private Dictionary<string, List<string>> dependingObjectNamesCache;
// The mapping of object definition objects, keyed by object name.
private readonly Dictionary<string, IObjectDefinition> objectDefinitionMap;
// List of object definition names, in registration order.
private List<string> objectDefinitionNames = new List<string>(256);
// Resolver to use for checking if an object definition is an autowire candidate
private IAutowireCandidateResolver autowireCandidateResolver = AutowireUtils.CreateAutowireCandidateResolver();
// Dictionary from dependency type to corresponding autowired value
private readonly IDictionary<Type, object> resolvableDependencies = new Dictionary<Type, object>();
// map of singleton and non-singleton bean names, keyed by dependency type
private readonly ConcurrentDictionary<Type, List<string>> allObjectNamesByType = new ConcurrentDictionary<Type, List<string>>();
// map of singleton-only bean names, keyed by dependency type
private readonly ConcurrentDictionary<Type, List<string>> singletonObjectNamesByType = new ConcurrentDictionary<Type, List<string>>();
// list of names of manually registered singletons, in registration order
private volatile OrderedSet<string> manualSingletonNames = new OrderedSet<string>();
// cached array of bean definition names in case of frozen configuration
private volatile string[] frozenObjectDefinitionNames;
// whether bean definition metadata may be cached for all beans
private volatile bool configurationFrozen;
/// <summary>
/// Creates a new instance of the
/// <see cref="Spring.Objects.Factory.Support.DefaultListableObjectFactory"/> class.
@@ -203,26 +235,28 @@ namespace Spring.Objects.Factory.Support
if (dependingObjectNamesCache == null)
{
dependingObjectNamesCache = new Dictionary<string, List<string>>();
IList<string> allObjectDefinitionNames = GetObjectDefinitionNames();
foreach (string name in allObjectDefinitionNames)
{
if (ContainsObjectDefinition(name))
{
RootObjectDefinition rod = GetMergedObjectDefinition(name, false);
if (rod.DependsOn != null)
{
foreach (var dependsOnName in rod.DependsOn)
{
if (!dependingObjectNamesCache.TryGetValue(dependsOnName, out dependingObjectNames))
{
dependingObjectNames = new List<string>();
dependingObjectNamesCache.Add(dependsOnName, dependingObjectNames);
}
dependingObjectNames.Add(name);
}
}
}
}
var allObjectDefinitionNames = GetObjectDefinitionNames();
for (var i = 0; i < allObjectDefinitionNames.Count; i++)
{
string name = allObjectDefinitionNames[i];
if (ContainsObjectDefinition(name))
{
RootObjectDefinition rod = GetMergedObjectDefinition(name, false);
if (rod.DependsOn != null)
{
foreach (var dependsOnName in rod.DependsOn)
{
if (!dependingObjectNamesCache.TryGetValue(dependsOnName, out dependingObjectNames))
{
dependingObjectNames = new List<string>();
dependingObjectNamesCache.Add(dependsOnName, dependingObjectNames);
}
dependingObjectNames.Add(name);
}
}
}
}
}
if (dependingObjectNamesCache.TryGetValue(objectName, out dependingObjectNames))
return dependingObjectNames;
@@ -265,31 +299,6 @@ namespace Spring.Objects.Factory.Support
return (rod.HasObjectType && checkedType.IsAssignableFrom(rod.ObjectType));
}
/// <summary>
/// The mapping of object depending object names, keyed by object name.
/// </summary>
private Dictionary<string, List<string>> dependingObjectNamesCache;
/// <summary>
/// The mapping of object definition objects, keyed by object name.
/// </summary>
private readonly Dictionary<string, IObjectDefinition> objectDefinitionMap;
/// <summary>
/// List of object definition names, in registration order.
/// </summary>
private readonly List<string> objectDefinitionNames = new List<string>();
/// <summary>
/// Resolver to use for checking if an object definition is an autowire candidate
/// </summary>
private IAutowireCandidateResolver autowireCandidateResolver = AutowireUtils.CreateAutowireCandidateResolver();
/// <summary>
/// IDictionary from dependency type to corresponding autowired value
/// </summary>
private readonly IDictionary<Type, object> resolvableDependencies = new Dictionary<Type, object>();
/// <summary>
/// Return the number of objects defined in this registry.
/// </summary>
@@ -297,10 +306,7 @@ namespace Spring.Objects.Factory.Support
/// The number of objects defined in this registry.
/// </value>
/// <seealso cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry.ObjectDefinitionCount"/>
public int ObjectDefinitionCount
{
get { return objectDefinitionMap.Count; }
}
public int ObjectDefinitionCount => objectDefinitionMap.Count;
/// <summary>
/// Check if this registry contains a object definition with the given
@@ -332,51 +338,123 @@ namespace Spring.Objects.Factory.Support
/// If the object definition is invalid.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.Support.IObjectDefinitionRegistry.RegisterObjectDefinition(string, IObjectDefinition)"/>
public override void RegisterObjectDefinition(
string name, IObjectDefinition objectDefinition)
public override void RegisterObjectDefinition(string name, IObjectDefinition objectDefinition)
{
if (objectDefinition is AbstractObjectDefinition)
if (objectDefinition is AbstractObjectDefinition abstractObjectDefinition)
{
try
{
((AbstractObjectDefinition)objectDefinition).Validate();
abstractObjectDefinition.Validate();
}
catch (ObjectDefinitionValidationException ex)
{
throw new ObjectDefinitionStoreException(
objectDefinition.ResourceDescription,
abstractObjectDefinition.ResourceDescription,
name,
"Validation of object definition failed.",
ex);
}
}
IObjectDefinition oldObjectDefinition;
if (objectDefinitionMap.TryGetValue(name, out oldObjectDefinition))
if (objectDefinitionMap.TryGetValue(name, out var existingDefinition))
{
if (!AllowObjectDefinitionOverriding)
{
throw new ObjectDefinitionStoreException(
string.Format(
"Cannot register object definition [{0}] for object '{1}': there's already [{2}] bound.",
objectDefinition, name, oldObjectDefinition));
$"Cannot register object definition [{objectDefinition}] for object '{name}': there's already [{existingDefinition}] bound.");
}
else
if (log.IsDebugEnabled)
{
if (log.IsDebugEnabled)
{
log.Debug(
string.Format(
"Overriding object definition for object '{0}': replacing [{1}] with [{2}].",
name, oldObjectDefinition, objectDefinition));
}
log.Debug(
$"Overriding object definition for object '{name}': replacing [{existingDefinition}] with [{objectDefinition}].");
}
objectDefinitionMap[name] = objectDefinition;
}
else
{
objectDefinitionNames.Add(name);
if (HasObjectCreationStarted)
{
// Cannot modify startup-time collection elements anymore (for stable iteration)
lock (objectDefinitionMap)
{
objectDefinitionMap[name] = objectDefinition;
var updatedDefinitions = new List<string>(objectDefinitionNames.Count + 1);
updatedDefinitions.AddRange(objectDefinitionNames);
updatedDefinitions.Add(name);
objectDefinitionNames = updatedDefinitions;
if (manualSingletonNames.Contains(name))
{
OrderedSet<string> updatedSingletons = new OrderedSet<string>(manualSingletonNames);
updatedSingletons.Remove(name);
manualSingletonNames = updatedSingletons;
}
}
}
else
{
// Still in startup registration phase
objectDefinitionMap[name] = objectDefinition;
objectDefinitionNames.Add(name);
manualSingletonNames.Remove(name);
}
frozenObjectDefinitionNames = null;
}
if (existingDefinition != null || ContainsSingleton(name))
{
ResetObjectDefinition(name);
}
objectDefinitionMap[name] = objectDefinition;
}
/// <summary>
/// Reset all bean definition caches for the given bean,
/// including the caches of beans that are derived from it.
///</summary>
/// <remarks>
/// Called after an existing bean definition has been replaced or removed,
/// triggering <see cref="DefaultListableObjectFactory.ClearMergedObjectDefinition" />, <see cref="DestroySingleton" />
/// and <see cref="IMergedObjectDefinitionPostProcessor.ResetObjectDefinition" /> on the
/// given bean and on all bean definitions that have the given bean as parent.
/// </remarks>
/// <param name="objectName">The name of the object to reset</param>
protected void ResetObjectDefinition(string objectName)
{
// Remove the merged bean definition for the given bean, if already created.
ClearMergedObjectDefinition(objectName);
// Remove corresponding bean from singleton cache, if any. Shouldn't usually
// be necessary, rather just meant for overriding a context's default beans
// (e.g. the default StaticMessageSource in a StaticApplicationContext).
DestroySingleton(objectName);
// Notify all post-processors that the specified bean definition has been reset.
for (var i = 0; i < ObjectPostProcessors.Count; i++)
{
IObjectPostProcessor processor = ObjectPostProcessors[i];
if (processor is IMergedObjectDefinitionPostProcessor mergedObjectDefinitionPostProcessor)
{
mergedObjectDefinitionPostProcessor.ResetObjectDefinition(objectName);
}
}
// Reset all bean definitions that have the given bean as parent (recursively).
for (var i = 0; i < objectDefinitionNames.Count; i++)
{
string bdName = objectDefinitionNames[i];
if (objectName != bdName)
{
var bd = objectDefinitionMap[bdName];
if (objectName == bd.ParentName)
{
ResetObjectDefinition(bdName);
}
}
}
}
/// <summary>
/// Ensure that all non-lazy-init singletons are instantiated, also
@@ -477,6 +555,77 @@ namespace Spring.Objects.Factory.Support
}
}
}
public override void ClearMetadataCache()
{
base.ClearMetadataCache();
ClearByTypeCache();
}
/// <summary>
/// Remove any assumptions about by-type mappings.
/// </summary>
private void ClearByTypeCache()
{
allObjectNamesByType.Clear();
singletonObjectNamesByType.Clear();
}
public void FreezeConfiguration()
{
configurationFrozen = true;
frozenObjectDefinitionNames = objectDefinitionNames.ToArray();
}
public bool ConfigurationFrozen => configurationFrozen;
public override void RegisterSingleton(string beanName, object singletonObject)
{
base.RegisterSingleton(beanName, singletonObject);
if (HasObjectCreationStarted)
{
// Cannot modify startup-time collection elements anymore (for stable iteration)
lock (objectDefinitionMap)
{
if (!objectDefinitionMap.ContainsKey(beanName))
{
var updatedSingletons = new OrderedSet<string>(manualSingletonNames);
updatedSingletons.Add(beanName);
manualSingletonNames = updatedSingletons;
}
}
}
else
{
// Still in startup registration phase
if (!objectDefinitionMap.ContainsKey(beanName))
{
manualSingletonNames.Add(beanName);
}
}
ClearByTypeCache();
}
protected override void DestroySingleton(string name)
{
base.DestroySingleton(name);
manualSingletonNames.Remove(name);
ClearByTypeCache();
}
/// <summary>
/// Determines whether the metadata for the specified object name is eligible for caching.
/// </summary>
/// <param name="beanName">Name of the bean.</param>
/// <returns>
/// <c>true</c> if [is object eligible for metadata caching] [the specified bean name]; otherwise, <c>false</c>.
/// </returns>
protected override bool IsObjectEligibleForMetadataCaching(string beanName)
{
return (ConfigurationFrozen || base.IsObjectEligibleForMetadataCaching(beanName));
}
/// <summary>
/// Return the registered
@@ -523,17 +672,16 @@ namespace Spring.Objects.Factory.Support
}
name = TransformedObjectName(name);
IObjectDefinition definition;
if (!objectDefinitionMap.TryGetValue(name, out definition))
if (!objectDefinitionMap.TryGetValue(name, out var definition))
{
if (!includeAncestors || ParentObjectFactory == null)
{
return null;
}
else if (ParentObjectFactory is AbstractObjectFactory)
if (ParentObjectFactory is AbstractObjectFactory abstractObjectFactory)
{
definition =
((AbstractObjectFactory)ParentObjectFactory).GetObjectDefinition(name, includeAncestors);
definition = abstractObjectFactory.GetObjectDefinition(name, includeAncestors);
}
}
return definition;
@@ -548,7 +696,7 @@ namespace Spring.Objects.Factory.Support
/// are defined. Respects any Parent-Child hierarchy the factory is participating in.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectDefinitionNames()"/>
public IList<string> GetObjectDefinitionNames()
public IReadOnlyList<string> GetObjectDefinitionNames()
{
return GetObjectDefinitionNames(false);
}
@@ -562,20 +710,19 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
public IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestors)
{
IList<string> results = new List<string>(objectDefinitionNames);
var listableObjectFactory = ParentObjectFactory as IListableObjectFactory;
if (includeAncestors && listableObjectFactory != null)
if (!includeAncestors || !(ParentObjectFactory is IListableObjectFactory listableObjectFactory))
{
foreach (var name in listableObjectFactory.GetObjectDefinitionNames(includeAncestors))
return objectDefinitionNames;
}
var results = new List<string>(objectDefinitionNames);
foreach (var name in listableObjectFactory.GetObjectDefinitionNames(includeAncestors: true))
{
if (!results.Contains(name))
{
if (!results.Contains(name))
{
results.Add(name);
}
results.Add(name);
}
}
@@ -626,7 +773,7 @@ namespace Spring.Objects.Factory.Support
/// are defined.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectNamesForType(Type)"/>
public IList<string> GetObjectNamesForType(Type type)
public IReadOnlyList<string> GetObjectNamesForType(Type type)
{
return GetObjectNamesForType(type, true, true);
}
@@ -654,7 +801,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNames<T>()
public IReadOnlyList<string> GetObjectNames<T>()
{
return GetObjectNamesForType(typeof(T));
}
@@ -680,9 +827,24 @@ namespace Spring.Objects.Factory.Support
/// are defined.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectNamesForType(Type, bool, bool)"/>
public IList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
List<string> objectNames = DoGetObjectNamesForType(type, includePrototypes, includeFactoryObjects);
if (!ConfigurationFrozen || type == null || !includeFactoryObjects)
{
return DoGetObjectNamesForType(type, includePrototypes, includeFactoryObjects);
}
ConcurrentDictionary<Type, List<string>> cache =
(includePrototypes ? allObjectNamesByType : singletonObjectNamesByType);
if (cache.TryGetValue(type, out var objectNames))
{
return objectNames;
}
objectNames = DoGetObjectNamesForType(type, includePrototypes, true);
cache[type] = objectNames;
return objectNames;
}
@@ -710,18 +872,18 @@ namespace Spring.Objects.Factory.Support
/// for all object names.
/// </typeparam>
/// <param name="includePrototypes">
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// </param>
/// <param name="includeFactoryObjects">
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// </param>
/// <returns>
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
{
return GetObjectNamesForType(typeof(T), includePrototypes, includeFactoryObjects);
}
@@ -745,7 +907,7 @@ namespace Spring.Objects.Factory.Support
/// If the objects could not be created.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectsOfType(Type)"/>
public IDictionary<string, object> GetObjectsOfType(Type type)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type)
{
return GetObjectsOfType(type, true, true);
}
@@ -777,7 +939,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, T> GetObjects<T>()
public IReadOnlyDictionary<string, T> GetObjects<T>()
{
Dictionary<string, T> result = new Dictionary<string, T>();
DoGetObjectsOfType(typeof(T), true, true, result);
@@ -808,7 +970,7 @@ namespace Spring.Objects.Factory.Support
/// If any of the objects could not be created.
/// </exception>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectsOfType(Type, bool, bool)"/>
public IDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
Dictionary<string, object> result = new Dictionary<string, object>();
DoGetObjectsOfType(type, includePrototypes, includeFactoryObjects, result);
@@ -874,7 +1036,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
{
Dictionary<string, T> result = new Dictionary<string, T>();
DoGetObjectsOfType(typeof(T), includePrototypes, includeFactoryObjects, result);
@@ -912,22 +1074,27 @@ namespace Spring.Objects.Factory.Support
/// </exception>
public override T GetObject<T>()
{
IList<string> objectNamesForType = GetObjectNamesForType(typeof(T));
var objectNamesForType = GetObjectNamesForType(typeof(T));
if (objectNamesForType.Count > 1)
{
IList<string> autowireCandidates = new List<string>();
var autowireCandidates = new List<string>();
foreach (var objectName in objectNamesForType)
{
if (GetObjectDefinition(objectName).IsAutowireCandidate)
{
autowireCandidates.Add(objectName);
}
}
if (autowireCandidates.Count > 0)
{
objectNamesForType = autowireCandidates;
}
}
if ((objectNamesForType == null) || (objectNamesForType.Count == 0))
if ((objectNamesForType == null) || objectNamesForType.Count == 0)
{
throw new NoSuchObjectDefinitionException(typeof(T).FullName, "Requested Type not Defined in the Context.");
}
@@ -936,15 +1103,14 @@ namespace Spring.Objects.Factory.Support
{
return (T)GetObject(objectNamesForType[0]);
}
else if (objectNamesForType.Count == 0 && ParentObjectFactory != null)
if (objectNamesForType.Count == 0 && ParentObjectFactory != null)
{
return ParentObjectFactory.GetObject<T>();
}
else
{
throw new NoSuchObjectDefinitionException(typeof(T), "expected single bean but found " +
objectNamesForType.Count + ": " + StringUtils.ArrayToCommaDelimitedString(objectNamesForType));
}
throw new NoSuchObjectDefinitionException(typeof(T), "expected single bean but found " +
objectNamesForType.Count + ": " + StringUtils.ArrayToCommaDelimitedString(objectNamesForType));
}
/// <summary>
@@ -974,9 +1140,10 @@ namespace Spring.Objects.Factory.Support
protected List<string> DoGetObjectNamesForType(Type type, bool includeNonSingletons, bool allowEagerInit)
{
List<string> result = new List<string>();
IList<string> objectNames = GetObjectDefinitionNames(true);
foreach (string s in objectNames)
var objectNames = GetObjectDefinitionNames(true);
for (var i = 0; i < objectNames.Count; i++)
{
string s = objectNames[i];
string objectName = s;
if (!IsAlias(objectName))
{
@@ -985,19 +1152,21 @@ namespace Spring.Objects.Factory.Support
RootObjectDefinition mod = GetMergedObjectDefinition(objectName, true);
// Only check object definition if it is complete
if (!mod.IsAbstract &&
(allowEagerInit || (mod.HasObjectType || !mod.IsLazyInit /*|| this.AllowEagerTypeLoading*/ ) &&
!RequiresEagerInitForType(mod.FactoryObjectName)))
(allowEagerInit ||
(mod.HasObjectType || !mod.IsLazyInit /*|| this.AllowEagerTypeLoading*/) &&
!RequiresEagerInitForType(mod.FactoryObjectName)))
{
bool isFactoryObject = IsFactoryObject(objectName, mod);
bool matchFound =
(allowEagerInit || !isFactoryObject || ContainsSingleton(objectName)) &&
(includeNonSingletons || IsSingleton(objectName)) && IsTypeMatch(objectName, type);
(allowEagerInit || !isFactoryObject || ContainsSingleton(objectName)) &&
(includeNonSingletons || IsSingleton(objectName)) && IsTypeMatch(objectName, type);
if (!matchFound && isFactoryObject)
{
// in case of a FactoryObject, try to match FactoryObject instance itself next
objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName);
matchFound = (includeNonSingletons || mod.IsSingleton) && IsTypeMatch(objectName, type);
}
if (matchFound)
{
result.Add(objectName);
@@ -1010,6 +1179,7 @@ namespace Spring.Objects.Factory.Support
{
throw;
}
// Probably contains a placeholder; lets ignore it for type matching purposes.
if (log.IsDebugEnabled)
{
@@ -1022,6 +1192,7 @@ namespace Spring.Objects.Factory.Support
{
throw;
}
// Probably contains a placeholder; lets ignore it for type matching purposes.
if (log.IsDebugEnabled)
{
@@ -1032,29 +1203,27 @@ namespace Spring.Objects.Factory.Support
}
// check singletons too, to catch manually registered singletons...
IList<string> singletonNames = GetSingletonNames();
foreach (string s in singletonNames)
foreach (string s in manualSingletonNames)
{
string objectName = s;
// only check if manually registered...
if (!ContainsObjectDefinition(objectName))
// in the case of an IFactoryObject, match the object created by the IFactoryObject...
if (IsFactoryObject(objectName))
{
// in the case of an IFactoryObject, match the object created by the IFactoryObject...
if (IsFactoryObject(objectName))
{
if ((includeNonSingletons || IsSingleton(objectName)) && IsTypeMatch(objectName, type))
{
result.Add(objectName);
continue;
}
objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName);
}
if (IsTypeMatch(objectName, type))
if ((includeNonSingletons || IsSingleton(objectName)) && IsTypeMatch(objectName, type))
{
result.Add(objectName);
continue;
}
objectName = ObjectFactoryUtils.BuildFactoryObjectName(objectName);
}
if (IsTypeMatch(objectName, type))
{
result.Add(objectName);
}
}
return result;
}
@@ -1132,7 +1301,7 @@ namespace Spring.Objects.Factory.Support
return TypeConversionUtils.ConvertValueIfNecessary(type, matchingObjects.Values, null);
}
else if (type.IsGenericType &&
(type.GetGenericTypeDefinition() == typeof(IList<>) || type.GetGenericTypeDefinition() == typeof(Spring.Collections.Generic.ISet<>) ||
(type.GetGenericTypeDefinition() == typeof(IList<>) || type.GetGenericTypeDefinition() == typeof(Collections.Generic.ISet<>) ||
type.GetGenericTypeDefinition() == typeof(IDictionary<,>)))
{
var isDictionary = (type.GetGenericTypeDefinition() == typeof (IDictionary<,>));
@@ -1268,7 +1437,7 @@ namespace Spring.Objects.Factory.Support
protected bool MatchesObjectName(string objectName, string candidateName)
{
return (candidateName != null &&
(candidateName.Equals(objectName) || GetAliases(objectName).Contains(candidateName)));
(candidateName.Equals(objectName) || DoGetAliases(objectName).Contains(candidateName)));
}
/// <summary>
@@ -1285,8 +1454,7 @@ namespace Spring.Objects.Factory.Support
private Dictionary<string, object> FindAutowireCandidates(string objectName, Type requiredType, DependencyDescriptor descriptor)
{
IList<string> candidateNames =
ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.Eager);
var candidateNames = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(this, requiredType, true, descriptor.Eager);
var result = new Dictionary<string, object>(candidateNames.Count);
foreach (var entry in resolvableDependencies)

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,14 +18,10 @@
#endregion
#region Imports
using System.Collections.Generic;
using Spring.Objects.Factory.Config;
#endregion
namespace Spring.Objects.Factory.Support
{
/// <summary>
@@ -52,16 +48,13 @@ namespace Spring.Objects.Factory.Support
/// </summary>
bool IsObjectNameInUse(string objectName);
/// <summary>
/// Return the number of objects defined in the registry.
/// </summary>
/// <value>
/// The number of objects defined in the registry.
/// </value>
int ObjectDefinitionCount
{
get;
}
/// <summary>
/// Return the number of objects defined in the registry.
/// </summary>
/// <value>
/// The number of objects defined in the registry.
/// </value>
int ObjectDefinitionCount { get; }
/// <summary>
/// Return the names of all objects defined in this registry.
@@ -70,7 +63,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this registry, or an empty array
/// if none defined
/// </returns>
IList<string> GetObjectDefinitionNames();
IReadOnlyList<string> GetObjectDefinitionNames();
/// <summary>
/// Return the names of all objects defined in this registry.
@@ -81,8 +74,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this registry, if <code>includeAncestors</code> is <code>true</code> it includes
/// all objects in the defined parent factories, or an empty array if none defined
/// </returns>
IList<string> GetObjectDefinitionNames(bool includeAncestors);
IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestors);
/// <summary>
/// Check if this registry contains a object definition with the given name.
@@ -157,7 +149,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.Factory.NoSuchObjectDefinitionException">
/// If there's no such object definition.
/// </exception>
IList<string> GetAliases (string name);
IReadOnlyList<string> GetAliases (string name);
/// <summary>
/// Given a object name, create an alias. We typically use this method to

View File

@@ -0,0 +1,61 @@
#region License
// /*
// * Copyright 2018 the original author or authors.
// *
// * Licensed under the Apache License, Version 2.0 (the "License");
// * you may not use this file except in compliance with the License.
// * You may obtain a copy of the License at
// *
// * http://www.apache.org/licenses/LICENSE-2.0
// *
// * Unless required by applicable law or agreed to in writing, software
// * distributed under the License is distributed on an "AS IS" BASIS,
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// * See the License for the specific language governing permissions and
// * limitations under the License.
// */
#endregion
using System;
using Spring.Objects.Factory.Config;
namespace Spring.Objects.Factory.Support
{
/// <summary>
/// Post-processor callback interface for <i>merged</i> bean definitions at runtime.
/// <see cref="IObjectPostProcessor"/> implementations may implement this sub-interface in order
/// to post-process the merged bean definition (a processed copy of the original object
/// definition) that the Spring <see cref="IObjectFactory" /> uses to create a object instance.
/// </summary>
/// <remarks>
/// The <see cref="PostProcessMergedObjectDefinition" /> method may for example introspect
/// the object definition in order to prepare some cached metadata before post-processing
/// actual instances of a object. It is also allowed to modify the object definition but
/// <i>only</i> for definition properties which are actually intended for concurrent
/// modification. Essentially, this only applies to operations defined on the
/// <see cref="RootObjectDefinition" /> itself but not to the properties of its base classes.
/// </remarks>
public interface IMergedObjectDefinitionPostProcessor : IObjectPostProcessor
{
/// <summary>
/// Post-process the given merged object definition for the specified object.
/// </summary>
/// <param name="objectDefinition">The merged object definition for the object</param>
/// <param name="objectType">The actual type of the managed object instance</param>
/// <param name="objectName">The name of the object</param>
/// <see cref="AbstractAutowireCapableObjectFactory.ApplyMergedObjectDefinitionPostProcessors" />
void PostProcessMergedObjectDefinition(RootObjectDefinition objectDefinition, Type objectType, string objectName);
/// <summary>
/// A notification that the object definition for the specified name has been reset,
/// and that this post-processor should clear any metadata for the affected object.
/// </summary>
/// <remarks>
/// The default implementation is empty.
/// </remarks>
/// <param name="objectName">The name of the object</param>
void ResetObjectDefinition(string objectName);
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -96,7 +96,7 @@ namespace Spring.Objects.Factory.Support
AssertUtils.ArgumentNotNull(registry, "registry");
registry.RegisterObjectDefinition(objectDefinition.ObjectName, objectDefinition.ObjectDefinition);
IList<string> aliases = objectDefinition.Aliases;
var aliases = objectDefinition.Aliases;
for (int i = 0; i < aliases.Count; ++i)
{
string alias = aliases[i];

View File

@@ -1,5 +1,3 @@
#region License
/*
* Copyright 2002-2010 the original author or authors.
*
@@ -16,8 +14,6 @@
* limitations under the License.
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
@@ -52,7 +48,7 @@ namespace Spring.Objects.Factory.Support
/// <param name="objectFactory">The object factory.</param>
public ObjectDefinitionValueResolver(AbstractObjectFactory objectFactory)
{
this.log = LogManager.GetLogger(this.GetType());
log = LogManager.GetLogger(GetType());
this.objectFactory = objectFactory;
}
@@ -349,14 +345,12 @@ namespace Spring.Objects.Factory.Support
/// <returns>A reference to another object in the factory.</returns>
protected virtual object ResolveReference(IObjectDefinition definition, string name, string argumentName, RuntimeObjectReference reference)
{
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(
string.Format(CultureInfo.InvariantCulture, "Resolving reference from property '{0}' in object '{1}' to object '{2}'.",
argumentName, name, reference.ObjectName));
}
#endregion
try
{
@@ -365,9 +359,8 @@ namespace Spring.Objects.Factory.Support
if (null == objectFactory.ParentObjectFactory)
{
throw new ObjectCreationException(definition.ResourceDescription, name,
string.Format(
"Can't resolve reference to '{0}' in parent factory: " + "no parent factory available.",
reference.ObjectName));
$"Can't resolve reference to '{reference.ObjectName}' in parent factory: " +
"no parent factory available.");
}
return objectFactory.ParentObjectFactory.GetObject(reference.ObjectName);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,10 +56,7 @@ namespace Spring.Objects.Factory.Support
/// <summary>
/// Determine whether this object factory treats object names case-sensitive or not.
/// </summary>
public bool IsCaseSensitive
{
get { return true; }
}
public bool IsCaseSensitive => true;
/// <summary>
/// Return the number of objects defined in the factory.
@@ -67,10 +64,7 @@ namespace Spring.Objects.Factory.Support
/// <value>
/// The number of objects defined in the factory.
/// </value>
public int ObjectDefinitionCount
{
get { return objects.Count; }
}
public int ObjectDefinitionCount => objects.Count;
/// <summary>
/// Return an instance of the given object name.
@@ -78,10 +72,7 @@ namespace Spring.Objects.Factory.Support
/// <param name="name">The name of the object to return.</param>
/// <returns>The instance of the object.</returns>
/// <seealso cref="Spring.Objects.Factory.IObjectFactory.GetObject(string)"/>
public object this[string name]
{
get { return GetObject(name); }
}
public object this[string name] => GetObject(name);
/// <summary>
/// Determines whether the object with the given name matches the specified type.
@@ -492,7 +483,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.Factory.NoSuchObjectDefinitionException">
/// If there's no such object definition.
/// </exception>
public IList<string> GetAliases(string name)
public IReadOnlyList<string> GetAliases(string name)
{
return StringUtils.EmptyStrings;
}
@@ -545,7 +536,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames()
public IReadOnlyList<string> GetObjectDefinitionNames()
{
List<string> names = new List<string>(objects.Keys);
return names;
@@ -560,7 +551,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this factory, if <code>includeAncestors</code> is <code>true</code> includes all
/// objects defined in parent factories, or an empty array if none are defined.
/// </returns>
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
public IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestors)
{
throw new NotSupportedException("StaticListableObjectFactory does not contain object definitions.");
}
@@ -620,7 +611,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNamesForType(Type type)
public IReadOnlyList<string> GetObjectNamesForType(Type type)
{
return GetObjectNamesForType(type, true, true);
}
@@ -648,7 +639,7 @@ namespace Spring.Objects.Factory.Support
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNames<T>()
public IReadOnlyList<string> GetObjectNames<T>()
{
return GetObjectNamesForType(typeof(T));
}
@@ -682,7 +673,7 @@ namespace Spring.Objects.Factory.Support
/// are defined.
/// </returns>
/// <seealso cref="Spring.Objects.Factory.IListableObjectFactory.GetObjectNamesForType(Type, bool, bool)"/>
public IList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
bool isFactoryType = (type != null && typeof(IFactoryObject).IsAssignableFrom(type));
List<string> matches = new List<string>();
@@ -735,18 +726,18 @@ namespace Spring.Objects.Factory.Support
/// for all object names.
/// </typeparam>
/// <param name="includePrototypes">
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// Whether to include prototype objects too or just singletons (also applies to
/// <see cref="Spring.Objects.Factory.IFactoryObject"/>s).
/// </param>
/// <param name="includeFactoryObjects">
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// Whether to include <see cref="Spring.Objects.Factory.IFactoryObject"/>s too
/// or just normal objects.
/// </param>
/// <returns>
/// The names of all objects defined in this factory, or an empty array if none
/// are defined.
/// </returns>
public IList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
{
return GetObjectNamesForType(typeof(T), includePrototypes, includeFactoryObjects);
}
@@ -791,7 +782,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, object> GetObjectsOfType(Type type)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type)
{
return GetObjectsOfType(type, true, true);
}
@@ -823,7 +814,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, T> GetObjects<T>()
public IReadOnlyDictionary<string, T> GetObjects<T>()
{
Dictionary<string, T> collector = new Dictionary<string, T>();
DoGetObjectsOfType(typeof(T), true, true, collector);
@@ -856,7 +847,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
Dictionary<string, object> collector = new Dictionary<string, object>();
DoGetObjectsOfType(type, includeFactoryObjects, includePrototypes, collector);
@@ -924,7 +915,7 @@ namespace Spring.Objects.Factory.Support
/// <exception cref="Spring.Objects.ObjectsException">
/// If the objects could not be created.
/// </exception>
public IDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
{
Dictionary<string, T> collector = new Dictionary<string, T>();
DoGetObjectsOfType(typeof(T), includeFactoryObjects, includePrototypes, collector);
@@ -962,7 +953,7 @@ namespace Spring.Objects.Factory.Support
/// </exception>
public T GetObject<T>()
{
IList<string> objectNamesForType = GetObjectNamesForType(typeof(T));
var objectNamesForType = GetObjectNamesForType(typeof(T));
if ((objectNamesForType == null) || (objectNamesForType.Count == 0))
{
throw new NoSuchObjectDefinitionException(typeof(T).FullName, "Requested Type not Defined in the Context.");

View File

@@ -1,5 +1,3 @@
#region License
/*
* Copyright 2002-2005 the original author or authors.
*
@@ -16,10 +14,6 @@
* limitations under the License.
*/
#endregion
#region Imports
using System;
using System.Globalization;
using System.IO;
@@ -29,8 +23,6 @@ using Spring.Core.IO;
using Spring.Objects.Factory.Config;
using Spring.Objects.Factory.Support;
#endregion
namespace Spring.Objects.Factory.Xml
{
/// <summary>
@@ -47,24 +39,14 @@ namespace Spring.Objects.Factory.Xml
/// <author>Rick Evans (.NET)</author>
public class DefaultObjectDefinitionDocumentReader : IObjectDefinitionDocumentReader
{
#region Constants
/// <summary>
/// The shared <see cref="Common.Logging.ILog"/> instance for this class (and derived classes).
/// </summary>
protected static readonly ILog log =
LogManager.GetLogger(typeof(DefaultObjectDefinitionDocumentReader));
#endregion
#region Fields
private XmlReaderContext readerContext;
#endregion
#region Constructor (s) / Destructor
/// <summary>
/// Creates a new instance of the DefaultObjectDefinitionDocumentReader class.
/// </summary>
@@ -72,10 +54,6 @@ namespace Spring.Objects.Factory.Xml
{
}
#endregion
#region Properties
/// <summary>
/// Gets the reader context.
/// </summary>
@@ -85,10 +63,6 @@ namespace Spring.Objects.Factory.Xml
get { return readerContext; }
}
#endregion
#region Methods
/// <summary>
/// Read object definitions from the given DOM element, and register
/// them with the given object registry.
@@ -109,15 +83,11 @@ namespace Spring.Objects.Factory.Xml
this.readerContext = readerContext;
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug("Loading object definitions.");
}
#endregion
XmlElement root = doc.DocumentElement;
ObjectDefinitionParserHelper parserHelper = CreateHelper(readerContext, root);
@@ -129,18 +99,11 @@ namespace Spring.Objects.Factory.Xml
PostProcessXml(root);
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(
string.Format(
"Found {0} <{1}> elements defining objects.",
readerContext.Registry.ObjectDefinitionCount,
ObjectDefinitionConstants.ObjectElement));
$"Found {readerContext.Registry.ObjectDefinitionCount} <{ObjectDefinitionConstants.ObjectElement}> elements defining objects.");
}
#endregion
}
/// <summary>
@@ -153,101 +116,97 @@ namespace Spring.Objects.Factory.Xml
/// in case an error happens during parsing and registering object definitions
/// </exception>
protected virtual void ParseObjectDefinitions(XmlElement root, ObjectDefinitionParserHelper helper)
{
if (helper.IsDefaultNamespace(root.NamespaceURI))
{
foreach (XmlNode node in root.ChildNodes)
{
if (node.NodeType != XmlNodeType.Element) continue;
try
{
XmlElement element = (XmlElement)node;
if (helper.IsDefaultNamespace(element.NamespaceURI))
{
ParseDefaultElement(element, helper);
}
else
{
helper.ParseCustomElement(element);
}
}
catch (ObjectDefinitionStoreException)
{
throw;
}
catch (Exception ex)
{
helper.ReaderContext.ReportException(node, null, "Failed parsing element", ex);
}
}
{
if (helper.IsDefaultNamespace(root.NamespaceURI))
{
foreach (XmlNode node in root.ChildNodes)
{
if (node.NodeType != XmlNodeType.Element) continue;
try
{
XmlElement element = (XmlElement)node;
if (helper.IsDefaultNamespace(element.NamespaceURI))
{
ParseDefaultElement(element, helper);
}
else
{
helper.ParseCustomElement(element);
}
}
catch (ObjectDefinitionStoreException)
{
throw;
}
catch (Exception ex)
{
helper.ReaderContext.ReportException(node, null, "Failed parsing element", ex);
}
}
}
else
{
helper.ParseCustomElement(root);
{
helper.ParseCustomElement(root);
}
}
private void ParseDefaultElement(XmlElement element, ObjectDefinitionParserHelper helper)
{
if (element.LocalName == ObjectDefinitionConstants.ImportElement)
{
ImportObjectDefinitionResource(element);
}
else if (element.LocalName == ObjectDefinitionConstants.AliasElement)
{
ParseAlias(element, helper.ReaderContext.Registry);
}
else if (element.LocalName == ObjectDefinitionConstants.ObjectElement)
{
ProcessObjectDefinition(element, helper);
}
}
/// <summary>
/// Process an alias element.
/// </summary>
protected virtual void ProcessAlias(XmlElement element)
{
this.ParseAlias(element, this.ReaderContext.Registry);
}
/// <summary>
/// Process the object element
/// </summary>
protected virtual void ProcessObjectDefinition(XmlElement element, ObjectDefinitionParserHelper helper)
{
// TODO: add event handling
try
{
ObjectDefinitionHolder bdHolder = helper.ParseObjectDefinitionElement(element);
if (bdHolder == null)
{
return;
}
bdHolder = helper.DecorateObjectDefinitionIfRequired(element, bdHolder);
if (log.IsDebugEnabled)
{
log.Debug(string.Format(CultureInfo.InvariantCulture, "Registering object definition with id '{0}'.", bdHolder.ObjectName));
}
ObjectDefinitionReaderUtils.RegisterObjectDefinition(bdHolder, ReaderContext.Registry);
// TODO: Send registration event.
// ReaderContext.FireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
catch (ObjectDefinitionStoreException)
{
throw;
}
}
private void ParseDefaultElement(XmlElement element, ObjectDefinitionParserHelper helper)
{
if (element.LocalName == ObjectDefinitionConstants.ImportElement)
{
ImportObjectDefinitionResource(element);
}
else if (element.LocalName == ObjectDefinitionConstants.AliasElement)
{
ParseAlias(element, helper.ReaderContext.Registry);
}
else if (element.LocalName == ObjectDefinitionConstants.ObjectElement)
{
ProcessObjectDefinition(element, helper);
}
}
/// <summary>
/// Process an alias element.
/// </summary>
protected virtual void ProcessAlias(XmlElement element)
{
this.ParseAlias(element, this.ReaderContext.Registry);
}
/// <summary>
/// Process the object element
/// </summary>
protected virtual void ProcessObjectDefinition(XmlElement element, ObjectDefinitionParserHelper helper)
{
// TODO: add event handling
try
{
ObjectDefinitionHolder bdHolder = helper.ParseObjectDefinitionElement(element);
if (bdHolder == null)
{
return;
}
bdHolder = helper.DecorateObjectDefinitionIfRequired(element, bdHolder);
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(string.Format(CultureInfo.InvariantCulture, "Registering object definition with id '{0}'.", bdHolder.ObjectName));
}
#endregion
ObjectDefinitionReaderUtils.RegisterObjectDefinition(bdHolder, ReaderContext.Registry);
// TODO: Send registration event.
// ReaderContext.FireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
catch (ObjectDefinitionStoreException)
{
throw;
}
catch (Exception ex)
{
throw new ObjectDefinitionStoreException(
string.Format("Failed parsing object definition '{0}'", element.OuterXml), ex);
$"Failed parsing object definition '{element.OuterXml}'", ex);
}
}
@@ -264,8 +223,6 @@ namespace Spring.Objects.Factory.Xml
string location = resource.GetAttribute(ObjectDefinitionConstants.ImportResourceAttribute);
try
{
#region Instrumentation
if (log.IsDebugEnabled)
{
log.Debug(string.Format(
@@ -273,8 +230,6 @@ namespace Spring.Objects.Factory.Xml
"Attempting to import object definitions from '{0}'.", location));
}
#endregion
IResource importResource = ReaderContext.Resource.CreateRelative(location);
ReaderContext.Reader.LoadObjectDefinitions(importResource);
}
@@ -370,7 +325,5 @@ namespace Spring.Objects.Factory.Xml
// {
// return "There is no parser registered for namespace '" + namespaceURI + "'";
// }
#endregion
}
}

View File

@@ -405,7 +405,11 @@ namespace Spring.Objects.Factory.Xml
/// <remarks>
/// This method may be used as a last resort to post-process an object definition before it gets added to the registry.
/// </remarks>
protected virtual ObjectDefinitionHolder CreateObjectDefinitionHolder(XmlElement element, IConfigurableObjectDefinition definition, string objectName, IList<string> aliases)
protected virtual ObjectDefinitionHolder CreateObjectDefinitionHolder(
XmlElement element,
IConfigurableObjectDefinition definition,
string objectName,
IReadOnlyList<string> aliases)
{
return new ObjectDefinitionHolder(definition, objectName, aliases);
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,3 @@
#region License
/*
* Copyright © 2002-2011 the original author or authors.
*
@@ -16,16 +14,10 @@
* limitations under the License.
*/
#endregion
#region Imports
using System;
using System.Collections;
using System.Reflection;
#endregion
namespace Spring.Util
{
/// <summary>
@@ -533,8 +525,6 @@ namespace Spring.Util
}
}
#region StableSort Utility Classes
private class Entry
{
private class EntryComparer : IComparer
@@ -573,7 +563,5 @@ namespace Spring.Util
Value = value;
}
}
#endregion
}
}

View File

@@ -303,11 +303,12 @@ namespace Spring.Util
if (RemotingServices.IsTransparentProxy(obj))
{
RealProxy rp = RemotingServices.GetRealProxy(obj);
if (rp is IRemotingTypeInfo)
if (rp is IRemotingTypeInfo remotingTypeInfo)
{
return ((IRemotingTypeInfo) rp).CanCastTo(type, obj);
return remotingTypeInfo.CanCastTo(type, obj);
}
else if (rp != null)
if (rp != null)
{
type = rp.GetProxiedType();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,7 @@ namespace Spring.Data.NHibernate.Bytecode
/// <returns>A reference to the created object.</returns>
public object CreateInstance(Type type)
{
IList<string> namesForType = listableObjectFactory.GetObjectNamesForType(type);
var namesForType = listableObjectFactory.GetObjectNamesForType(type);
return namesForType.Count > 0 ? listableObjectFactory.GetObject(namesForType[0], type) : Activator.CreateInstance(type);
}
@@ -57,7 +57,7 @@ namespace Spring.Data.NHibernate.Bytecode
/// <returns>A reference to the created object </returns>
public object CreateInstance(Type type, bool nonPublic)
{
IList<string> namesForType = listableObjectFactory.GetObjectNamesForType(type);
var namesForType = listableObjectFactory.GetObjectNamesForType(type);
return namesForType.Count > 0 ? listableObjectFactory.GetObject(namesForType[0], type) : Activator.CreateInstance(type);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -50,7 +50,7 @@ namespace Spring.Data.NHibernate.Bytecode
/// <returns>The new instance.</returns>
public override object CreateInstance()
{
IList<string> namesForType = listableObjectFactory.GetObjectNamesForType(mappedType);
var namesForType = listableObjectFactory.GetObjectNamesForType(mappedType);
if (namesForType.Count > 0)
{
return listableObjectFactory.GetObject(namesForType[0], mappedType);

View File

@@ -1,5 +1,5 @@
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -670,7 +670,7 @@ namespace Spring.Data.NHibernate
{
Type hibCommandType = db.CreateCommand().GetType();
IList<string> providerNames = ctx.GetObjectNamesForType(typeof(DbProvider), true, false);
var providerNames = ctx.GetObjectNamesForType(typeof(DbProvider), true, false);
string hibCommandAQN = hibCommandType.AssemblyQualifiedName;
string hibCommandAQNWithoutVersion = hibCommandType.FullName + ", " + hibCommandType.Assembly.GetName().Name;
foreach (string providerName in providerNames)

View File

@@ -1,5 +1,5 @@
/*
* Copyright <20> 2002-2011 the original author or authors.
* Copyright <20> 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -128,10 +128,11 @@ namespace Spring.Data.Common
ctx = new XmlApplicationContext(DBPROVIDER_CONTEXTNAME, true, new string[] { DBPROVIDER_DEFAULT_RESOURCE_NAME });
}
IList<string> dbProviderNames = ctx.GetObjectNames<IDbProvider>();
if (log.IsInfoEnabled)
{
log.Info(string.Format("{0} DbProviders Available. [{1}]", dbProviderNames.Count, StringUtils.CollectionToCommaDelimitedString(dbProviderNames)));
var dbProviderNames = ctx.GetObjectNames<IDbProvider>();
log.Info(
$"{dbProviderNames.Count} DbProviders Available. [{StringUtils.CollectionToCommaDelimitedString(dbProviderNames)}]");
}
}
catch (Exception e)

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2011 the original author or authors.
* Copyright <20> 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -72,7 +72,7 @@ namespace Spring.Messaging.Core
MessageQueueFactoryObject mqfo = new MessageQueueFactoryObject();
mqfo.MessageCreatorDelegate = messageQueueCreatorDelegate;
applicationContext.ObjectFactory.RegisterSingleton(messageQueueObjectName, mqfo);
IDictionary<string, MessageQueueMetadataCache> caches = applicationContext.GetObjects<MessageQueueMetadataCache>();
var caches = applicationContext.GetObjects<MessageQueueMetadataCache>();
foreach (KeyValuePair<string, MessageQueueMetadataCache> entry in caches)
{
entry.Value.Insert(mqfo.Path, new MessageQueueMetadata(mqfo.RemoteQueue, mqfo.RemoteQueueIsTransactional));

View File

@@ -56,7 +56,7 @@ namespace Spring.Messaging.Core
/// </summary>
public void Initialize()
{
IDictionary<string, MessageQueueFactoryObject> messageQueueDictionary = configurableApplicationContext.GetObjects<MessageQueueFactoryObject>();
var messageQueueDictionary = configurableApplicationContext.GetObjects<MessageQueueFactoryObject>();
lock (itemStore.SyncRoot)
{
foreach (KeyValuePair<string, MessageQueueFactoryObject> entry in messageQueueDictionary)

View File

@@ -1,19 +1,19 @@
#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.
/*
* 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
@@ -85,11 +85,13 @@ namespace Spring.Objects.Factory.Xml
return objectName;
}
protected override ObjectDefinitionHolder CreateObjectDefinitionHolder(XmlElement element, IConfigurableObjectDefinition definition, string objectName, IList<string> aliasesArray)
protected override ObjectDefinitionHolder CreateObjectDefinitionHolder(
XmlElement element,
IConfigurableObjectDefinition definition,
string objectName,
IReadOnlyList<string> aliasesArray)
{
IWebObjectDefinition webDefinition = definition as IWebObjectDefinition;
if (webDefinition != null)
if (definition is IWebObjectDefinition webDefinition)
{
if (definition.IsSingleton
&& element.HasAttribute(ObjectDefinitionConstants.ScopeAttribute))

View File

@@ -59,18 +59,16 @@ namespace Spring.Web.Support
RenderHeader(res.Output, context.Request.ApplicationPath);
IConfigurableApplicationContext appContext =
WebApplicationContext.Current as IConfigurableApplicationContext;
if (appContext == null)
if (!(WebApplicationContext.Current is IConfigurableApplicationContext appContext))
{
throw new InvalidOperationException(
"Implementations of IApplicationContext must also implement IConfigurableApplicationContext");
}
IList<string> names = appContext.GetObjectDefinitionNames();
foreach (string name in names)
var names = appContext.GetObjectDefinitionNames();
for (var i = 0; i < names.Count; i++)
{
string name = names[i];
RenderObjectDefinition(res.Output, name, appContext.ObjectFactory.GetObjectDefinition(name));
}

View File

@@ -55,7 +55,7 @@ namespace Spring.Aop.Framework.AutoProxy
public void DefaultExclusionPrefix()
{
DefaultAdvisorAutoProxyCreator aapc = (DefaultAdvisorAutoProxyCreator)ObjectFactory.GetObject(ADVISOR_APC_OBJECT_NAME);
Assert.AreEqual(ADVISOR_APC_OBJECT_NAME + DefaultAdvisorAutoProxyCreator.SEPARATOR, aapc.AdvisorObjectNamePrefix);
Assert.AreEqual(ADVISOR_APC_OBJECT_NAME + DefaultAdvisorAutoProxyCreator.Separator, aapc.AdvisorObjectNamePrefix);
Assert.IsFalse(aapc.UsePrefix);
}

View File

@@ -18,6 +18,7 @@
#endregion
using System.Linq;
using NUnit.Framework;
using Spring.Context.Attributes;
using Spring.Context.Support;

View File

@@ -18,6 +18,7 @@
#endregion
using System.Linq;
using NUnit.Framework;
using Spring.Context.Attributes;
using Spring.Context.Support;

View File

@@ -1,7 +1,5 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,10 +14,6 @@
* limitations under the License.
*/
#endregion
#region Imports
using System;
using System.Collections.Generic;
using System.Globalization;
@@ -28,8 +22,6 @@ using Spring.Core.IO;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;
#endregion
namespace Spring.Context.Support
{
[TestFixture]
@@ -47,20 +39,14 @@ namespace Spring.Context.Support
{
}
protected override Type RequiredType
{
get { return typeof (MockApplicationContext); }
}
protected override Type RequiredType => typeof (MockApplicationContext);
protected override void InitApplicationContext()
{
_init = true;
}
public bool Init
{
get { return _init; }
}
public bool Init => _init;
}
internal class MyContext2 : IApplicationContext
@@ -69,43 +55,25 @@ namespace Spring.Context.Support
{
}
#region IApplicationContext Members
public IApplicationContext ParentContext => null;
public IApplicationContext ParentContext
{
get { return null; }
set
{
}
}
public DateTime StartupDate
{
get { return new DateTime(); }
}
public DateTime StartupDate => new DateTime();
#pragma warning disable 67
public event ApplicationEventHandler ContextEvent;
#pragma warning restore 67
public long StartupDateMilliseconds
{
get { return 0; }
}
public long StartupDateMilliseconds => 0;
public string Name
{
get { return AbstractApplicationContext.DefaultRootContextName; }
get => AbstractApplicationContext.DefaultRootContextName;
set
{
}
}
#endregion
#region IListableObjectFactory Members
public IObjectDefinition GetObjectDefinition(string name)
public IObjectDefinition GetObjectDefinition(string name)
{
return null;
}
@@ -115,7 +83,7 @@ namespace Spring.Context.Support
return null;
}
public IList<string> GetObjectDefinitionNames(bool includeAncestors)
public IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestors)
{
return null;
}
@@ -125,47 +93,47 @@ namespace Spring.Context.Support
return null;
}
public IList<string> GetObjectNamesForType(Type type)
public IReadOnlyList<string> GetObjectNamesForType(Type type)
{
return null;
}
public IList<string> GetObjectNames<T>()
public IReadOnlyList<string> GetObjectNames<T>()
{
return null;
}
public IList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
public IList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyList<string> GetObjectNames<T>(bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
IList<string> IListableObjectFactory.GetObjectDefinitionNames()
IReadOnlyList<string> IListableObjectFactory.GetObjectDefinitionNames()
{
return null;
}
public IDictionary<string, object> GetObjectsOfType(Type type)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type)
{
return null;
}
public IDictionary<string, T> GetObjects<T>()
public IReadOnlyDictionary<string, T> GetObjects<T>()
{
return null;
}
public IDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, object> GetObjectsOfType(Type type, bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
public IDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
public IReadOnlyDictionary<string, T> GetObjects<T>(bool includePrototypes, bool includeFactoryObjects)
{
return null;
}
@@ -175,36 +143,23 @@ namespace Spring.Context.Support
throw new NotImplementedException();
}
public int ObjectDefinitionCount
{
get { return 0; }
}
public int ObjectDefinitionCount => 0;
public bool ContainsObjectDefinition(string name)
{
return false;
}
#endregion
public bool IsCaseSensitive => true;
#region IObjectFactory Members
public bool IsCaseSensitive
{
get { return true; }
}
public object this[string name]
{
get { return null; }
}
public object this[string name] => null;
public bool ContainsObject(string name)
{
return false;
}
public IList<string> GetAliases(string name)
public IReadOnlyList<string> GetAliases(string name)
{
return null;
}
@@ -291,24 +246,13 @@ namespace Spring.Context.Support
return null;
}
#endregion
public IObjectFactory ParentObjectFactory => null;
#region IHierarchicalObjectFactory Members
public IObjectFactory ParentObjectFactory
{
get { return null; }
}
public bool ContainsLocalObject(string name)
public bool ContainsLocalObject(string name)
{
return false;
}
#endregion
#region IMessageSource Members
public string GetMessage(IMessageSourceResolvable resolvable, CultureInfo culture)
{
return null;
@@ -353,19 +297,11 @@ namespace Spring.Context.Support
{
}
#endregion
#region IResourceLoader Members
public IResource GetResource(string location)
{
return null;
}
#endregion
#region IEventRepository Members
public void PublishEvents(object sourceObject)
{
throw new NotImplementedException();
@@ -392,8 +328,6 @@ namespace Spring.Context.Support
throw new NotImplementedException();
}
#endregion
public void PublishEvent(object sender, ApplicationEventArgs e)
{
throw new NotImplementedException();
@@ -422,10 +356,7 @@ namespace Spring.Context.Support
_init = true;
}
public bool Init
{
get { return _init; }
}
public bool Init => _init;
}

View File

@@ -22,21 +22,20 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
#endregion
namespace Spring.Objects.Factory {
/// <summary>
/// Unit tests for the AbstractListableObjectFactory class.
namespace Spring.Objects.Factory
{
/// <summary>
/// Unit tests for the AbstractListableObjectFactory class.
/// </summary>
/// <author>Rod Johnson</author>
/// <author>Rick Evans (.NET)</author>
public abstract class AbstractListableObjectFactoryTests :
AbstractObjectFactoryTests {
AbstractObjectFactoryTests
{
/// <summary>
/// Subclasses must initialize this (via the derived ObjectFactory property).
/// </summary>
@@ -46,73 +45,70 @@ namespace Spring.Objects.Factory {
{
if (!(ObjectFactory is IListableObjectFactory))
{
throw new SystemException ("IListableObjectFactory required...");
throw new SystemException("IListableObjectFactory required...");
}
return (IListableObjectFactory) ObjectFactory;
}
}
}
/// <summary>
/// Subclasses can override this.
/// </summary>
[Test]
public virtual void Count ()
public virtual void Count()
{
AssertCount (19);
AssertCount(19);
}
protected internal void AssertCount (int count)
protected internal void AssertCount(int count)
{
IList<string> defnames = ListableObjectFactory.GetObjectDefinitionNames(true);
Assert.IsTrue (
var defnames = ListableObjectFactory.GetObjectDefinitionNames(true);
Assert.IsTrue(
defnames.Count == count,
string.Format ("We should have {0} objects, not {1}.", count, defnames.Count));
$"We should have {count} objects, not {defnames.Count}.");
}
[Test]
public virtual void ObjectCount ()
public virtual void ObjectCount()
{
AssertTestObjectCount (12);
AssertTestObjectCount(12);
}
public virtual void AssertTestObjectCount (int count)
public virtual void AssertTestObjectCount(int count)
{
IList<string> defnames =
ListableObjectFactory.GetObjectNamesForType(typeof (TestObject));
Assert.IsTrue (
var defnames = ListableObjectFactory.GetObjectNamesForType(typeof(TestObject));
Assert.IsTrue(
defnames.Count == count,
string.Format ("We should have {0} objects for class {1}, not {2}.", count, typeof (TestObject).FullName, defnames.Count));
$"We should have {count} objects for class {typeof(TestObject).FullName}, not {defnames.Count}.");
}
[Test]
public virtual void GetDefinitionsForNoSuchClass ()
public virtual void GetDefinitionsForNoSuchClass()
{
IList<string> defnames =
ListableObjectFactory.GetObjectNamesForType (typeof (string));
Assert.IsTrue (defnames.Count == 0, "No string definitions");
var defnames = ListableObjectFactory.GetObjectNamesForType(typeof(string));
Assert.IsTrue(defnames.Count == 0, "No string definitions");
}
/// <summary>
/// Check that count refers to factory class, not
/// object class (we don't know what type factories may return,
/// and it may even change over time).
/// </summary>
[Test]
public virtual void GetCountForFactoryClass ()
public virtual void GetCountForFactoryClass()
{
int count =
ListableObjectFactory.GetObjectNamesForType (
typeof (IFactoryObject)).Count;
Assert.IsTrue (
int count = ListableObjectFactory.GetObjectNamesForType(typeof(IFactoryObject)).Count;
Assert.IsTrue(
count == 2,
string.Format ("Should have 2 factories, not {0}.", count));
$"Should have 2 factories, not {count}.");
}
[Test]
public virtual void ContainsObjectDefinition ()
public virtual void ContainsObjectDefinition()
{
Assert.IsTrue (ListableObjectFactory.ContainsObjectDefinition ("rod"));
Assert.IsTrue (ListableObjectFactory.ContainsObjectDefinition ("roderick"));
Assert.IsTrue(ListableObjectFactory.ContainsObjectDefinition("rod"));
Assert.IsTrue(ListableObjectFactory.ContainsObjectDefinition("roderick"));
}
}
}
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,3 @@
#region License
/*
* Copyright 2004 the original author or authors.
*
@@ -16,12 +14,11 @@
* limitations under the License.
*/
#endregion
using System;
using System.Collections;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Reflection;
using System.Runtime.Serialization;
using NUnit.Framework;
@@ -139,7 +136,7 @@ namespace Spring.Objects.Factory
def.FactoryMethodName = "CreateTestObject";
DefaultListableObjectFactory lof = new DefaultListableObjectFactory();
lof.RegisterObjectDefinition("factoryObject", def);
IDictionary<string, TestObject> objs = lof.GetObjects<TestObject>();
var objs = lof.GetObjects<TestObject>();
Assert.AreEqual(1, objs.Count);
}
@@ -153,7 +150,7 @@ namespace Spring.Objects.Factory
DefaultListableObjectFactory lof = new DefaultListableObjectFactory();
lof.RegisterObjectDefinition("factoryObject", def);
lof.RegisterObjectDefinition("target", new RootObjectDefinition(typeof(TestObjectCreator)));
IDictionary<string, TestObject> objs = lof.GetObjects<TestObject>();
var objs = lof.GetObjects<TestObject>();
Assert.AreEqual(1, objs.Count);
}
@@ -165,7 +162,7 @@ namespace Spring.Objects.Factory
= new RootObjectDefinition(typeof(TestGenericObject<int, string>));
def.FactoryMethodName = "CreateList<int>";
lof.RegisterObjectDefinition("foo", def);
IDictionary<string, object> objs = lof.GetObjectsOfType(typeof(List<int>));
var objs = lof.GetObjectsOfType(typeof(List<int>));
Assert.AreEqual(1, objs.Count);
}
@@ -179,7 +176,7 @@ namespace Spring.Objects.Factory
DefaultListableObjectFactory lof = new DefaultListableObjectFactory();
lof.RegisterObjectDefinition("factoryObject", def);
lof.RegisterObjectDefinition("target", new RootObjectDefinition(typeof(TestGenericObject<int, string>)));
IDictionary<string, object> objs = lof.GetObjectsOfType(typeof(TestGenericObject<string, int>));
var objs = lof.GetObjectsOfType(typeof(TestGenericObject<string, int>));
Assert.AreEqual(1, objs.Count);
}
@@ -217,7 +214,7 @@ namespace Spring.Objects.Factory
typeof(StaticFactoryMethodObject));
def.FactoryMethodName = "CreateObject";
lof.RegisterObjectDefinition("foo", def);
IDictionary<string, object> objs = lof.GetObjectsOfType(typeof(DBNull));
var objs = lof.GetObjectsOfType(typeof(DBNull));
Assert.AreEqual(1, objs.Count,
"Must be looking at the RETURN TYPE of the factory method, " +
"and hence get one DBNull object back.");
@@ -394,15 +391,11 @@ namespace Spring.Objects.Factory
return true;
}
#region IInstantiationAwareObjectPostProcessor Members
public IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, IList<PropertyInfo> pis, object objectInstance, string objectName)
{
return pvs;
}
#endregion
public object PostProcessAfterInitialization(object obj, string objectName)
{
return obj;
@@ -444,15 +437,11 @@ namespace Spring.Objects.Factory
return true;
}
#region IInstantiationAwareObjectPostProcessor Members
public IPropertyValues PostProcessPropertyValues(IPropertyValues pvs, IList<PropertyInfo> pis, object objectInstance, string objectName)
{
return pvs;
}
#endregion
public object PostProcessAfterInitialization(object obj, string objectName)
{
throw new NotImplementedException();
@@ -582,7 +571,7 @@ namespace Spring.Objects.Factory
TestObject test = (TestObject)lof.GetObject("test");
Assert.AreEqual(singletonObject, lof.GetObject("singletonObject"));
Assert.AreEqual(singletonObject, test.Spouse);
IDictionary<string, object> objectsOfType = lof.GetObjectsOfType(typeof(TestObject), false, true);
var objectsOfType = lof.GetObjectsOfType(typeof(TestObject), false, true);
Assert.AreEqual(2, objectsOfType.Count);
Assert.IsTrue(objectsOfType.Values.Contains(test));
Assert.IsTrue(objectsOfType.Values.Contains(singletonObject));
@@ -1450,7 +1439,7 @@ namespace Spring.Objects.Factory
{
TestObject instance = new TestObject();
DefaultListableObjectFactory fac = new DefaultListableObjectFactory();
Assert.Throws<ArgumentException>(() => fac.ConfigureObject(instance, null));
Assert.Throws<ArgumentNullException>(() => fac.ConfigureObject(instance, null));
}
[Test]
@@ -1663,8 +1652,6 @@ namespace Spring.Objects.Factory
Assert.AreSame(testObject, resultObject);
}
#region TestObjectPostProcessor
private class TestObjectPostProcessor : IObjectPostProcessor
{
private object other;
@@ -1685,9 +1672,6 @@ namespace Spring.Objects.Factory
}
}
#endregion
[Test]
public void ConfigureObjectAppliesObjectPostProcessorsUsingDefinition()
{
@@ -1724,8 +1708,6 @@ namespace Spring.Objects.Factory
Assert.IsNotNull(c);
}
#region GetObjectNamesForTypeFindsFactoryObjects
private class A : IFactoryObject, ISerializable
{
public object GetObject()
@@ -1749,8 +1731,6 @@ namespace Spring.Objects.Factory
}
}
#endregion
[Test]
public void GetObjectDefinitionNamesOnlyFromChild()
{
@@ -1817,13 +1797,56 @@ namespace Spring.Objects.Factory
DefaultListableObjectFactory of = new DefaultListableObjectFactory();
of.RegisterObjectDefinition("mod", new RootObjectDefinition(typeof(A)));
IList<string> names = of.GetObjectNamesForType(typeof (ISerializable), false, false);
var names = of.GetObjectNamesForType(typeof (ISerializable), false, false);
Assert.IsNotEmpty((ICollection) names);
Assert.AreEqual("&mod", names[0]);
}
[Test, MaxTime(1000)]
public void TestRegistrationOfManyBeanDefinitionsIsFastEnough()
{
var bf = new DefaultListableObjectFactory();
bf.RegisterObjectDefinition("b", new RootObjectDefinition(typeof(B)));
for (int i = 0; i < 100_000; i++) {
bf.RegisterObjectDefinition("a" + i, new RootObjectDefinition(typeof(A)));
}
}
#region Helper Classes
[Test, MaxTime(1000)]
public void TestRegistrationOfManySingletonsIsFastEnough()
{
// Assume.group(TestGroup.PERFORMANCE);
var bf = new DefaultListableObjectFactory();
bf.RegisterObjectDefinition("b", new RootObjectDefinition(typeof(B)));
// bf.getBean("b");
for (int i = 0; i < 100000; i++) {
bf.RegisterSingleton("a" + i, new A());
}
}
[Test, MaxTime(3000)]
public void TestPrototypeCreationIsFastEnough()
{
var lbf = new DefaultListableObjectFactory();
var rbd = new RootObjectDefinition(typeof(TestObject))
{
Scope = "prototype"
};
lbf.RegisterObjectDefinition("test", rbd);
//lbf.FreezeConfiguration();
for (int i = 0; i < 100_000; i++)
{
lbf.GetObject("test");
}
}
public class B
{
}
public interface IParent
{
@@ -1928,8 +1951,6 @@ namespace Spring.Objects.Factory
InitWasCalled = true;
}
}
#endregion
}
public class Foo

View File

@@ -22,6 +22,7 @@
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using Spring.Objects.Factory.Config;
@@ -68,14 +69,14 @@ namespace Spring.Objects.Factory
[Test]
public void ObjectNamesIncludingAncestors()
{
IList<string> names = ObjectFactoryUtils.ObjectNamesIncludingAncestors(_factory);
var names = ObjectFactoryUtils.ObjectNamesIncludingAncestors(_factory);
Assert.AreEqual(6, names.Count);
}
[Test]
public void ObjectNamesForTypeIncludingAncestors()
{
IList<string> names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, typeof(ITestObject));
var names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, typeof(ITestObject));
// includes 2 TestObjects from IFactoryObjects (DummyFactory definitions)
Assert.AreEqual(4, names.Count);
Assert.IsTrue(names.Contains("test"));
@@ -92,7 +93,7 @@ namespace Spring.Objects.Factory
DefaultListableObjectFactory child = new DefaultListableObjectFactory(root);
child.RegisterObjectDefinition("excludeLocalObject", new RootObjectDefinition(typeof(Hashtable)));
IList<string> names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(child, typeof(ArrayList));
var names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(child, typeof(ArrayList));
// "excludeLocalObject" matches on the parent, but not the local object definition
Assert.AreEqual(0, names.Count);

View File

@@ -35,7 +35,7 @@ namespace Spring.Objects.Factory
[Test]
public void ObjectNamesIncludingAncestorsPreserveOrderOfRegistration()
{
IList<string> names = ObjectFactoryUtils.ObjectNamesIncludingAncestors(_factory);
var names = ObjectFactoryUtils.ObjectNamesIncludingAncestors(_factory);
Assert.AreEqual(5, names.Count);
Assert.AreEqual(new string[] { "objA", "objB", "objC", "obj2A", "obj2C" }, names);
}
@@ -43,7 +43,7 @@ namespace Spring.Objects.Factory
[Test]
public void ObjectNamesForTypeIncludingAncestorsPreserveOrderOfRegistration()
{
IList<string> names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, _expectedtype);
var names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, _expectedtype);
Assert.AreEqual(5, names.Count);
Assert.AreEqual(new string[] { "objA", "objB", "objC", "obj2A", "obj2C" }, names);
}
@@ -51,7 +51,7 @@ namespace Spring.Objects.Factory
[Test]
public void ObjectNamesForTypeIncludingAncestorsPrototypesAndFactoryObjectsPreserveOrderOfRegistration()
{
IList<string> names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, _expectedtype, false, false);
var names = ObjectFactoryUtils.ObjectNamesForTypeIncludingAncestors(_factory, _expectedtype, false, false);
Assert.AreEqual(5, names.Count);
Assert.AreEqual(new string[] { "objA", "objB", "objC", "obj2A", "obj2C" }, names);
}

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <EFBFBD> 2002-2011 the original author or authors.
* Copyright © 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -22,6 +22,7 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using Common.Logging;
using Common.Logging.Simple;
@@ -195,12 +196,12 @@ namespace Spring.Objects.Factory.Xml
{
IResource resource = new ReadOnlyXmlTestResource("collections.xml", GetType());
XmlObjectFactory xof = new XmlObjectFactory(resource);
IList<string> objectNames = xof.GetObjectDefinitionNames();
var objectNames = xof.GetObjectDefinitionNames();
TestObject tb1 = (TestObject) xof.GetObject("aliased");
TestObject alias1 = (TestObject) xof.GetObject("myalias");
Assert.IsTrue(tb1 == alias1);
IList<string> tb1Aliases = xof.GetAliases("aliased");
var tb1Aliases = xof.GetAliases("aliased");
Assert.AreEqual(1, tb1Aliases.Count);
Assert.IsTrue(tb1Aliases.Contains("myalias"));
Assert.IsTrue(objectNames.Contains("aliased"));
@@ -211,7 +212,7 @@ namespace Spring.Objects.Factory.Xml
TestObject alias3 = (TestObject) xof.GetObject("alias2");
Assert.IsTrue(tb2 == alias2);
Assert.IsTrue(tb2 == alias3);
IList<string> tb2Aliases = xof.GetAliases("multiAliased");
var tb2Aliases = xof.GetAliases("multiAliased");
Assert.AreEqual(2, tb2Aliases.Count);
Assert.IsTrue(tb2Aliases.Contains("alias1"));
Assert.IsTrue(tb2Aliases.Contains("alias2"));
@@ -225,7 +226,7 @@ namespace Spring.Objects.Factory.Xml
Assert.IsTrue(tb3 == alias4);
Assert.IsTrue(tb3 == alias5);
IList<string> tb3Aliases = xof.GetAliases("aliasWithoutId1");
var tb3Aliases = xof.GetAliases("aliasWithoutId1");
Assert.AreEqual(2, tb2Aliases.Count);
Assert.IsTrue(tb3Aliases.Contains("aliasWithoutId2"));
Assert.IsTrue(tb3Aliases.Contains("aliasWithoutId3"));

View File

@@ -439,7 +439,7 @@ namespace Spring.Objects.Factory.Xml
</objects>";
stream = new MemoryStream(Encoding.UTF8.GetBytes(xml));
XmlObjectFactory factory = new XmlObjectFactory(new InputStreamResource(stream, string.Empty));
IList<string> names = factory.GetObjectDefinitionNames();
var names = factory.GetObjectDefinitionNames();
// mmm, how is one to test this? I have no idea what the generated name is...
Assert.AreEqual(2, names.Count, "Should have got two object names, one of which is autogenerated.");
}
@@ -765,7 +765,7 @@ namespace Spring.Objects.Factory.Xml
// abstract objects should not match
//TODO add overloaded GetObjectOfType with 1 arg
IDictionary<string, object> tbs = parent.GetObjectsOfType(typeof(TestObject), true, true);
var tbs = parent.GetObjectsOfType(typeof(TestObject), true, true);
Assert.AreEqual(2, tbs.Count);
Assert.IsTrue(tbs.ContainsKey("inheritedTestObjectPrototype"));
Assert.IsTrue(tbs.ContainsKey("inheritedTestObjectSingleton"));

View File

@@ -30,17 +30,14 @@ namespace Spring.Validation
{
private bool _wasCalled;
public bool WasCalled
{
get { return _wasCalled; }
}
public bool WasCalled => _wasCalled;
public override bool Validate(object validationContext, IDictionary<string, object> contextParams, IValidationErrors errors)
public override bool Validate(object validationContext, IDictionary<string, object> contextParams,
IValidationErrors errors)
{
_wasCalled = true;
return base.Validate (validationContext, contextParams, errors);
return base.Validate(validationContext, contextParams, errors);
}
}
/// <summary>
@@ -49,9 +46,9 @@ namespace Spring.Validation
/// <author>Aleksandar Seovic</author>
public class TrueValidator : BaseTestValidator
{
public TrueValidator()
{}
{
}
/// <summary>
/// Validates test object.
@@ -68,7 +65,7 @@ namespace Spring.Validation
{
public FalseValidator()
{
this.Actions.Add(new ErrorMessageAction("error", "errors"));
Actions.Add(new ErrorMessageAction("error", "errors"));
}
/// <summary>
@@ -84,26 +81,23 @@ namespace Spring.Validation
public sealed class MockObjectDefinitionRegistry : IObjectDefinitionRegistry
{
private IDictionary<string, IObjectDefinition> objects = new Dictionary<string, IObjectDefinition>();
private readonly IDictionary<string, IObjectDefinition> objects = new Dictionary<string, IObjectDefinition>();
public int ObjectDefinitionCount
public int ObjectDefinitionCount => objects.Count;
public IReadOnlyList<string> GetObjectDefinitionNames()
{
get { return this.objects.Count; }
return new List<string>(objects.Keys);
}
public IList<string> GetObjectDefinitionNames()
public IReadOnlyList<string> GetObjectDefinitionNames(bool includeAncestor)
{
return new List<string>(this.objects.Keys);
}
public IList<string> GetObjectDefinitionNames(bool includeAncestor)
{
return new List<string>(this.objects.Keys);
return new List<string>(objects.Keys);
}
public IList<IObjectDefinition> GetObjectDefinitions()
{
return new List<IObjectDefinition>(this.objects.Values);
return new List<IObjectDefinition>(objects.Values);
}
public bool ContainsObjectDefinition(string name)
@@ -113,17 +107,16 @@ namespace Spring.Validation
public IObjectDefinition GetObjectDefinition(string name)
{
IObjectDefinition definition;
objects.TryGetValue(name, out definition);
objects.TryGetValue(name, out var definition);
return definition;
}
public void RegisterObjectDefinition(string name, IObjectDefinition definition)
{
this.objects[name] = definition;
objects[name] = definition;
}
public IList<string> GetAliases(string name)
public IReadOnlyList<string> GetAliases(string name)
{
throw new NotImplementedException();
}
@@ -135,8 +128,7 @@ namespace Spring.Validation
public bool IsObjectNameInUse(string objectName)
{
return this.objects[objectName] != null;
return objects[objectName] != null;
}
}
}

View File

@@ -193,7 +193,7 @@ namespace Spring.Data.Common
//Initialize internal application context. factory
DbProviderFactory.GetDbProvider("SqlServer-2.0");
IApplicationContext ctx = DbProviderFactory.ApplicationContext;
IList<string> dbProviderNames = ctx.GetObjectNamesForType(typeof (IDbProvider));
var dbProviderNames = ctx.GetObjectNamesForType(typeof (IDbProvider));
Assert.IsTrue(dbProviderNames.Count > 0);
}
#endif

View File

@@ -1,7 +1,7 @@
#region License
/*
* Copyright <20> 2002-2011 the original author or authors.
* Copyright <20> 2002-2011 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -68,14 +68,14 @@ namespace Spring.Messaging.Nms.Config
[Test]
public void ObjectsCreated()
{
IDictionary<string, SimpleMessageListenerContainer> containers = ctx.GetObjects<SimpleMessageListenerContainer>();
var containers = ctx.GetObjects<SimpleMessageListenerContainer>();
Assert.AreEqual(3, containers.Count);
}
[Test]
public void ContainerConfiguration()
{
IDictionary<string, SimpleMessageListenerContainer> containers = ctx.GetObjects<SimpleMessageListenerContainer>();
var containers = ctx.GetObjects<SimpleMessageListenerContainer>();
IConnectionFactory defaultConnectionFactory = (IConnectionFactory) ctx.GetObject(DEFAULT_CONNECTION_FACTORY);
IConnectionFactory explicitConnectionFactory = (IConnectionFactory) ctx.GetObject(EXPLICIT_CONNECTION_FACTORY);

View File

@@ -103,7 +103,7 @@ namespace Spring.ServiceModel.Config
IApplicationContext ctx = new XmlApplicationContext(
ReadOnlyXmlTestResource.GetFilePath("ChannelFactoryObjectDefinitionParserTests.WithoutId.xml", this.GetType()));
IDictionary<string, IContract> channels = ctx.GetObjects<IContract>();
var channels = ctx.GetObjects<IContract>();
Assert.AreEqual(1, channels.Count);
}