diff --git a/BreakingChanges-1.2.txt b/BreakingChanges-1.2.txt
index 498d2970..728c8b4d 100644
--- a/BreakingChanges-1.2.txt
+++ b/BreakingChanges-1.2.txt
@@ -30,12 +30,19 @@ Spring.Core
A new property MsgDelivery has been added. The class, CachedMessageProducer, which is unlikely to be use by
end users, was directly upgraded to the latest API without any backwards compatibility support.
+4. AbstractApplicationContext.CaseSensitive renamed to AbstractApplicationContext.IsCaseSensitive
+
+
Spring.Aop
----------
1. AbstractAutoProxyCreator.FindEligibleAdvisors(Type) changed to
AbstractAutoProxyCreator.FindEligibleAdvisors(Type, Name)
+2. It is not possible to change a ProxyFactoryObject's product configuration at runtime
+ if IsSingleton==true since factory object singleton products get cached now.
+
+
Changes (1.2 RC1 to 1.2.0 or greater)
=====================================
diff --git a/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs b/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs
index 81f99df4..165cff20 100644
--- a/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs
+++ b/src/Spring/Spring.Aop/Aop/Framework/Adapter/DefaultAdvisorAdapterRegistry.cs
@@ -42,7 +42,7 @@ namespace Spring.Aop.Framework.Adapter
/// Aleksandar Seovic (.NET)
public class DefaultAdvisorAdapterRegistry : IAdvisorAdapterRegistry
{
- private IList adapters = new ArrayList();
+ private readonly IList adapters = new ArrayList();
///
/// Creates a new instance of the
diff --git a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs
index df790b0f..2ebf8fb8 100644
--- a/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs
+++ b/src/Spring/Spring.Aop/Aop/Framework/AutoProxy/DefaultAdvisorAutoProxyCreator.cs
@@ -21,6 +21,8 @@
#region Imports
using System;
+using System.Collections;
+using Spring.Context;
using Spring.Objects.Factory;
#endregion
@@ -35,7 +37,7 @@ namespace Spring.Aop.Framework.AutoProxy
/// Rod Johnson
/// Adhari C Mahendra (.NET)
/// Erich Eichinger (.NET)
- public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware
+ public class DefaultAdvisorAutoProxyCreator : AbstractAdvisorAutoProxyCreator, IObjectNameAware, IInitializingObject
{
///
/// Separator between prefix and remainder of object name
@@ -43,6 +45,7 @@ namespace Spring.Aop.Framework.AutoProxy
public static readonly string SEPARATOR = ".";
private bool usePrefix;
private string advisorObjectNamePrefix;
+ private IList cachedAdvisors;
#region Properties
@@ -97,7 +100,21 @@ namespace Spring.Aop.Framework.AutoProxy
}
}
- #endregion
+ #endregion
+
+ ///
+ /// Find all possible advisor candidates to use in auto-proxying
+ ///
+ /// the type of the object to be advised
+ /// the name of the object to be advised
+ /// the list of candidate advisors
+ protected override IList FindCandidateAdvisors(Type targetType, string targetName)
+ {
+ if (cachedAdvisors == null) {
+ cachedAdvisors = base.FindCandidateAdvisors(targetType, targetName);
+ }
+ return cachedAdvisors;
+ }
///
/// Whether the given advisor is eligible for the specified target.
@@ -109,5 +126,14 @@ namespace Spring.Aop.Framework.AutoProxy
{
return (!usePrefix || advisorName.StartsWith(advisorObjectNamePrefix));
}
- }
+
+ ///
+ /// Validate configuration
+ ///
+ public virtual void AfterPropertiesSet()
+ {
+ // eagerly resolve advisors at this stage already to prevent circular dep problems.
+ // TODO (EE): fix instantiation process to make test "AdvisorAutoProxyCreatorCircularReferencesTests" work.
+ cachedAdvisors = base.FindCandidateAdvisors(null, null);
+ }
}
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
index 5cffebf8..5c8ddfcc 100644
--- a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
+++ b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs
@@ -33,6 +33,7 @@ using Spring.Objects.Events;
using Spring.Objects.Events.Support;
using Spring.Objects.Factory;
using Spring.Objects.Factory.Config;
+using Spring.Objects.Factory.Support;
using Spring.Objects.Support;
using Spring.Util;
@@ -75,7 +76,7 @@ namespace Spring.Context.Support
///
///
public abstract class AbstractApplicationContext
- : ConfigurableResourceLoader, IConfigurableApplicationContext
+ : ConfigurableResourceLoader, IConfigurableApplicationContext, IObjectDefinitionRegistry
{
#region Constants
@@ -124,7 +125,7 @@ namespace Spring.Context.Support
///
/// The instance for this class.
///
- private static readonly ILog log = LogManager.GetLogger(typeof(AbstractApplicationContext));
+ protected readonly ILog log;
///
/// The instance we delegate
@@ -140,10 +141,10 @@ namespace Spring.Context.Support
private IApplicationContext _parentApplicationContext;
private readonly IList _objectFactoryPostProcessors;
- private IList _defaultObjectPostProcessors;
+ private readonly IList _defaultObjectPostProcessors;
private string _name;
private DateTime _startupDate;
- private readonly bool _caseSensitive;
+ private readonly bool _isCaseSensitive;
#endregion
@@ -196,8 +197,10 @@ namespace Spring.Context.Support
protected AbstractApplicationContext(string name, bool caseSensitive,
IApplicationContext parentApplicationContext)
{
+ log = LogManager.GetLogger(this.GetType());
+
_name = (StringUtils.IsNullOrEmpty(name)) ? DefaultRootContextName : name;
- _caseSensitive = caseSensitive;
+ _isCaseSensitive = caseSensitive;
_parentApplicationContext = parentApplicationContext;
_objectFactoryPostProcessors = new ArrayList();
_defaultObjectPostProcessors = new ArrayList();
@@ -294,9 +297,9 @@ namespace Spring.Context.Support
/// Gets a flag indicating whether context should be case sensitive.
///
/// true if object lookups are case sensitive; otherwise, false.
- protected bool CaseSensitive
+ public bool IsCaseSensitive
{
- get { return _caseSensitive; }
+ get { return _isCaseSensitive; }
}
///
@@ -1517,6 +1520,9 @@ namespace Spring.Context.Support
/// This is an alternative to ContainsObject, ignoring an object
/// of the given name from an ancestor object factory.
///
+ ///
+ ///
+ ///
/// The name of the object to query.
///
/// true if objects with the specified name is defined in the local factory; otherwise, false.
@@ -1528,6 +1534,60 @@ namespace Spring.Context.Support
#endregion
+ #region IObjectDefinitionRegistry Members
+
+ ///
+ /// Determine whether the given object name is already in use within this context,
+ /// i.e. whether there is a local object. May be override by subclasses, the default
+ /// implementation simply returns
+ ///
+ public virtual bool IsObjectNameInUse(string objectName)
+ {
+ return ContainsLocalObject(objectName);
+ }
+
+ ///
+ /// Register a new object definition with this registry.
+ /// Must support
+ ///
+ /// and .
+ ///
+ /// The name of the object instance to register.
+ /// The definition of the object instance to register.
+ ///
+ ///
- /// This is an class, and as such exposes
- /// no public constructors.
- ///
- ///
- protected AbstractXmlApplicationContext() : this(null, true, null)
- {}
-
- ///
- /// Creates a new instance of the
- /// class
- /// with the given parent context.
- ///
- ///
- ///
- /// This is an class, and as such exposes
- /// no public constructors.
- ///
- ///
- /// The application context name.
- /// Flag specifying whether to make this context case sensitive or not.
- /// The parent context.
- protected AbstractXmlApplicationContext(string name, bool caseSensitive,
- IApplicationContext parentContext) : base(name, caseSensitive, parentContext)
- {}
-
- ///
- /// An array of resource locations, referring to the XML object
- /// definition files that this context is to be built with.
- ///
- ///
- ///
- /// Examples of the format of the various strings that would be
- /// returned by accessing this property can be found in the overview
- /// documentation of with the
- /// class.
- ///
- ///
- ///
- /// An array of resource locations, or if none.
- ///
- protected abstract string[] ConfigurationLocations { get; }
-
- ///
- /// Instantiates and populates the underlying
- /// with the object
- /// definitions yielded up by the
- /// method.
- ///
- ///
- /// In the case of errors encountered while refreshing the object factory.
- ///
- ///
- /// In the case of errors encountered reading any of the resources
- /// yielded by the method.
- ///
- ///
- protected override void RefreshObjectFactory()
- {
- // Shut down previous object factory, if any.
- IConfigurableListableObjectFactory oldObjectFactory = null;
- oldObjectFactory = _objectFactory;
-
- if (oldObjectFactory != null)
- {
- _objectFactory = null;
- oldObjectFactory.Dispose();
- }
-
- try
- {
- DefaultListableObjectFactory objectFactory = CreateObjectFactory();
- LoadObjectDefinitions(objectFactory);
-
- _objectFactory = objectFactory;
-
- #region Instrumentation
-
- if (log.IsDebugEnabled)
- {
- log.Debug(
- string.Format(
- "Refreshed ObjectFactory for application context '{0}'.",
- Name));
- }
-
- #endregion
- }
- catch (IOException ex)
- {
- throw new ApplicationContextException(
- string.Format(
- "I/O error parsing XML resource for application context '{0}'.",
- Name), ex);
- }
- catch (UriFormatException ex)
- {
- throw new ApplicationContextException(
- string.Format(
- "Error parsing resource locations [{0}] for application context '{1}'.",
- StringUtils.ArrayToCommaDelimitedString(ConfigurationLocations),
- Name), ex);
- }
- }
-
-
- ///
- /// Initialize the object definition reader used for loading the object
- /// definitions of this context.
- ///
- ///
- ///
- /// The default implementation of this method is a no-op; i.e. it does
- /// nothing. Can be overridden in subclasses to provide custom
- /// initialization of the supplied
- /// ; for example, a derived
- /// class may want to turn off XML validation.
- ///
- ///
- ///
- /// The object definition reader used by this context.
- ///
- protected virtual void InitObjectDefinitionReader(
- XmlObjectDefinitionReader objectDefinitionReader)
- {}
-
- ///
- /// Load the object definitions with the given
- /// .
- ///
- ///
- ///
- /// The lifecycle of the object factory is handled by
- /// ;
- /// therefore this method is just supposed to load and / or register
- /// object definitions.
- ///
- ///
- ///
- /// The reader containing object definitions.
- ///
- /// In case of object registration errors.
- ///
- ///
- /// In the case of errors encountered reading any of the resources
- /// yielded by the method.
- ///
- protected virtual void LoadObjectDefinitions(
- XmlObjectDefinitionReader objectDefinitionReader)
- {
- string[] locations = ConfigurationLocations;
- if (locations != null)
- {
- objectDefinitionReader.LoadObjectDefinitions(ConfigurationLocations);
- }
- }
-
-
- ///
- /// Loads the object definitions into the given object factory, typically through
- /// delegating to one or more object definition readers.
- ///
- /// The object factory to lead object definitions into
- ///
- ///
- protected virtual void LoadObjectDefinitions(DefaultListableObjectFactory objectFactory)
- {
- //Create a new XmlObjectDefinitionReader for the given ObjectFactory
- XmlObjectDefinitionReader objectDefinitionReader = CreateXmlObjectDefinitionReader(objectFactory);
-
- // Configure the bean definition reader with this context's
- // resource loading environment.
- objectDefinitionReader.ResourceLoader = this;
-
- // Allow a subclass to provide custom initialization of the reader,
- // then proceed with actually loading the object definitions.
- InitObjectDefinitionReader(objectDefinitionReader);
- LoadObjectDefinitions(objectDefinitionReader);
+ */
+
+#endregion
+
+#region Imports
+
+using System;
+using System.IO;
+using System.Threading;
+using Common.Logging;
+using Spring.Objects;
+using Spring.Objects.Factory.Config;
+using Spring.Objects.Factory.Support;
+using Spring.Objects.Factory.Xml;
+using Spring.Util;
+
+#endregion
+
+namespace Spring.Context.Support
+{
+ ///
+ /// Convenient abstract superclass for
+ /// implementations that
+ /// draw their configuration from XML documents containing object
+ /// definitions as understood by an
+ /// .
+ ///
+ /// Rod Johnson
+ /// Juergen Hoeller
+ /// Griffin Caprio (.NET)
+ public abstract class AbstractXmlApplicationContext : AbstractApplicationContext
+ {
+ private DefaultListableObjectFactory _objectFactory;
+
+ ///
+ /// Creates a new instance of the
+ ///
+ /// class.
+ ///
+ ///
+ ///
+ /// This is an class, and as such exposes
+ /// no public constructors.
+ ///
+ ///
+ protected AbstractXmlApplicationContext()
+ : this(null, true, null)
+ { }
+
+ ///
+ /// Creates a new instance of the
+ /// class
+ /// with the given parent context.
+ ///
+ ///
+ ///
+ /// This is an class, and as such exposes
+ /// no public constructors.
+ ///
+ ///
+ /// The application context name.
+ /// Flag specifying whether to make this context case sensitive or not.
+ /// The parent context.
+ protected AbstractXmlApplicationContext(string name, bool caseSensitive,
+ IApplicationContext parentContext)
+ : base(name, caseSensitive, parentContext)
+ { }
+
+ ///
+ /// An array of resource locations, referring to the XML object
+ /// definition files that this context is to be built with.
+ ///
+ ///
+ ///
+ /// Examples of the format of the various strings that would be
+ /// returned by accessing this property can be found in the overview
+ /// documentation of with the
+ /// class.
+ ///
+ ///
+ ///
+ /// An array of resource locations, or if none.
+ ///
+ protected abstract string[] ConfigurationLocations { get; }
+
+ ///
+ /// Instantiates and populates the underlying
+ /// with the object
+ /// definitions yielded up by the
+ /// method.
+ ///
+ ///
+ /// In the case of errors encountered while refreshing the object factory.
+ ///
+ ///
+ /// In the case of errors encountered reading any of the resources
+ /// yielded by the method.
+ ///
+ ///
+ protected override void RefreshObjectFactory()
+ {
+ // Shut down previous object factory, if any.
+ IConfigurableListableObjectFactory oldObjectFactory = null;
+ oldObjectFactory = Interlocked.Exchange(ref _objectFactory, null);
+
+ if (oldObjectFactory != null)
+ {
+ // _objectFactory = null;
+ oldObjectFactory.Dispose();
+ }
+
+ try
+ {
+ DefaultListableObjectFactory objectFactory = CreateObjectFactory();
+ LoadObjectDefinitions(objectFactory);
+
+ _objectFactory = objectFactory;
+
+ #region Instrumentation
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug(
+ string.Format(
+ "Refreshed ObjectFactory for application context '{0}'.",
+ Name));
+ }
+
+ #endregion
+ }
+ catch (IOException ex)
+ {
+ throw new ApplicationContextException(
+ string.Format(
+ "I/O error parsing XML resource for application context '{0}'.",
+ Name), ex);
+ }
+ catch (UriFormatException ex)
+ {
+ throw new ApplicationContextException(
+ string.Format(
+ "Error parsing resource locations [{0}] for application context '{1}'.",
+ StringUtils.ArrayToCommaDelimitedString(ConfigurationLocations),
+ Name), ex);
+ }
+ }
+
+
+ ///
+ /// Initialize the object definition reader used for loading the object
+ /// definitions of this context.
+ ///
+ ///
+ ///
+ /// The default implementation of this method is a no-op; i.e. it does
+ /// nothing. Can be overridden in subclasses to provide custom
+ /// initialization of the supplied
+ /// ; for example, a derived
+ /// class may want to turn off XML validation.
+ ///
+ ///
+ ///
+ /// The object definition reader used by this context.
+ ///
+ protected virtual void InitObjectDefinitionReader(
+ XmlObjectDefinitionReader objectDefinitionReader)
+ { }
+
+ ///
+ /// Load the object definitions with the given
+ /// .
+ ///
+ ///
+ ///
+ /// The lifecycle of the object factory is handled by
+ /// ;
+ /// therefore this method is just supposed to load and / or register
+ /// object definitions.
+ ///
+ ///
+ ///
+ /// The reader containing object definitions.
+ ///
+ /// In case of object registration errors.
+ ///
+ ///
+ /// In the case of errors encountered reading any of the resources
+ /// yielded by the method.
+ ///
+ protected virtual void LoadObjectDefinitions(
+ XmlObjectDefinitionReader objectDefinitionReader)
+ {
+ string[] locations = ConfigurationLocations;
+ if (locations != null)
+ {
+ objectDefinitionReader.LoadObjectDefinitions(ConfigurationLocations);
+ }
+ }
+
+
+ ///
+ /// Loads the object definitions into the given object factory, typically through
+ /// delegating to one or more object definition readers.
+ ///
+ /// The object factory to lead object definitions into
+ ///
+ ///
+ protected virtual void LoadObjectDefinitions(DefaultListableObjectFactory objectFactory)
+ {
+ //Create a new XmlObjectDefinitionReader for the given ObjectFactory
+ XmlObjectDefinitionReader objectDefinitionReader = CreateXmlObjectDefinitionReader(objectFactory);
+
+ // Configure the bean definition reader with this context's
+ // resource loading environment.
+ objectDefinitionReader.ResourceLoader = this;
+
+ // Allow a subclass to provide custom initialization of the reader,
+ // then proceed with actually loading the object definitions.
+ InitObjectDefinitionReader(objectDefinitionReader);
+ LoadObjectDefinitions(objectDefinitionReader);
}
///
@@ -246,57 +244,60 @@ namespace Spring.Context.Support
protected virtual XmlObjectDefinitionReader CreateXmlObjectDefinitionReader(DefaultListableObjectFactory objectFactory)
{
return new XmlObjectDefinitionReader(objectFactory);
- }
-
- ///
- /// Customizes the internal object factory used by this context.
- ///
- /// Called for each attempt.
- ///
- /// The default implementation is empty. Can be overriden in subclassses to customize
- /// DefaultListableBeanFatory's standard settings.
- ///
- /// The newly created object factory for this context
- protected virtual void CustomizeObjectFactory(DefaultListableObjectFactory objectFactory)
- {
-
- }
-
- ///
- /// Create an internal object factory for this context.
- ///
- ///
- ///
- /// Called for each attempt.
- /// This default implementation creates a
- ///
- /// with the internal object factory of this context's parent serving
- /// as the parent object factory. Can be overridden in subclasse,s
- /// for example to customize DefaultListableBeanFactory's settings.
- ///
- ///
- /// The object factory for this context.
- protected virtual DefaultListableObjectFactory CreateObjectFactory()
- {
- return new DefaultListableObjectFactory(CaseSensitive, GetInternalParentObjectFactory());
- }
-
- ///
- /// Subclasses must return their internal object factory here.
- ///
- ///
- /// The internal object factory for the application context.
- ///
- ///
- public override IConfigurableListableObjectFactory ObjectFactory
- {
- get
- {
- lock(SyncRoot)
- {
- return _objectFactory;
- }
- }
- }
- }
+ }
+
+ ///
+ /// Customizes the internal object factory used by this context.
+ ///
+ /// Called for each attempt.
+ ///
+ /// The default implementation is empty. Can be overriden in subclassses to customize
+ /// DefaultListableBeanFatory's standard settings.
+ ///
+ /// The newly created object factory for this context
+ protected virtual void CustomizeObjectFactory(DefaultListableObjectFactory objectFactory)
+ {
+ // noop
+ }
+
+ ///
+ /// Create an internal object factory for this context.
+ ///
+ ///
+ ///
+ /// Called for each attempt.
+ /// This default implementation creates a
+ ///
+ /// with the internal object factory of this context's parent serving
+ /// as the parent object factory. Can be overridden in subclasse,s
+ /// for example to customize DefaultListableBeanFactory's settings.
+ ///
+ ///
+ /// The object factory for this context.
+ protected virtual DefaultListableObjectFactory CreateObjectFactory()
+ {
+ return new DefaultListableObjectFactory(IsCaseSensitive, GetInternalParentObjectFactory());
+ }
+
+ ///
+ /// Subclasses must return their internal object factory here.
+ ///
+ ///
+ /// The internal object factory for the application context.
+ ///
+ ///
+ public override IConfigurableListableObjectFactory ObjectFactory
+ {
+ get { return _objectFactory; }
+ }
+
+ ///
+ /// Determine whether the given object name is already in use within this context's object factory,
+ /// i.e. whether there is a local object or alias registered under this name.
+ ///
+ public override bool IsObjectNameInUse(string objectName)
+ {
+ return _objectFactory.IsObjectNameInUse(objectName);
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs
index cfeee781..b7d6cef0 100644
--- a/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs
+++ b/src/Spring/Spring.Core/Context/Support/GenericApplicationContext.cs
@@ -1,5 +1,5 @@
-#region License
-
+#region License
+
/*
* Copyright 2002-2007 the original author or authors.
*
@@ -14,243 +14,166 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
-#endregion
-
-using System;
-using Spring.Core.IO;
-using Spring.Objects.Factory.Config;
-using Spring.Objects.Factory.Support;
-using Spring.Util;
-
-namespace Spring.Context.Support
-{
- ///
- /// Generic ApplicationContext implementation that holds a single internal
- /// instance and does not
- /// assume a specific object definition format.
- ///
- ///
- /// Implements the interface in order
- /// to allow for aplying any object definition readers to it.
- /// Typical usage is to register a variety of object definitions via the
- /// interface and then call
- /// to initialize those
- /// objects with application context semantics (handling
- /// , auto-detecting
- /// ObjectFactoryPostProcessors, etc).
- ///
- /// In contrast to other IApplicationContext implementations that create a new internal
- /// IObjectFactory instance for each refresh, the internal IObjectFactory of this context
- /// is available right from the start, to be able to register object definitions on it.
- /// may only be called once
- /// Usage examples
- ///
- /// GenericApplicationContext ctx = new GenericApplicationContext();
- ///
- ///
- ///
- /// Mark Pollack
- public class GenericApplicationContext : AbstractApplicationContext, IObjectDefinitionRegistry
- {
- private DefaultListableObjectFactory objectFactory;
-
- private bool refreshed = false;
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- public GenericApplicationContext()
- {
- objectFactory = new DefaultListableObjectFactory();
- }
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// if set to true names in the context are case sensitive.
- public GenericApplicationContext(bool caseSensitive)
- {
- objectFactory = new DefaultListableObjectFactory(caseSensitive);
- }
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The object factory instance to use for this context.
- public GenericApplicationContext(DefaultListableObjectFactory objectFactory)
- {
- AssertUtils.ArgumentNotNull(objectFactory, "objectFactory", "ObjectFactory must not be null");
- this.objectFactory = objectFactory;
- }
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The parent application context.
- public GenericApplicationContext(IApplicationContext parent)
- {
- objectFactory = new DefaultListableObjectFactory();
- ParentContext = parent;
- }
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The name of the application context.
- /// if set to true names in the context are case sensitive.
- /// The parent application context.
- public GenericApplicationContext(string name, bool caseSensitive, IApplicationContext parent) : this(caseSensitive)
- {
- Name = name;
- ParentContext = parent;
- }
-
-
- ///
- /// Initializes a new instance of the class.
- ///
- /// The object factory to use for this context
- /// The parent applicaiton context.
- public GenericApplicationContext(DefaultListableObjectFactory objectFactory, IApplicationContext parent) : this(objectFactory)
- {
- ParentContext = parent;
- }
-
-
-
- ///
- /// Gets the parent context, or if there is no
- /// parent context. Set the parent of this application context also setting
- /// the parent of the interanl ObjectFactory accordingly.
- ///
- /// The parent context
- ///
- /// The parent context, or if there is no
- /// parent.
- ///
- ///
- public override IApplicationContext ParentContext
- {
- get
- {
- return base.ParentContext;
- }
- set {
- base.ParentContext = value;
- objectFactory.ParentObjectFactory = GetInternalParentObjectFactory();
- }
- }
-
-
- ///
- /// Do nothing operation. We hold a single internal ObjectFactory and rely on callers
- /// to register objects throug our public methods (or the ObjectFactory's).
- ///
- ///
- /// In the case of errors encountered while refreshing the object factory.
- ///
- protected override void RefreshObjectFactory()
- {
- if (refreshed)
- {
- throw new InvalidOperationException(
- "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
- }
-
- refreshed = true;
- }
-
- ///
- /// Return the internal object factory of this application context.
- ///
- ///
- public override IConfigurableListableObjectFactory ObjectFactory
- {
- get { return objectFactory; }
- }
-
- ///
- /// Gets the underlying object factory of this context, available for
- /// registering object definitions.
- ///
- /// You need to call Refresh to initialize the
- /// objects factory and its contained objects with application context
- /// semantics (autodecting IObjectFactoryPostProcessors, etc).
- /// The internal object factory (as DefaultListableObjectFactory).
- public DefaultListableObjectFactory DefaultListableObjectFactory
- {
- get { return objectFactory; }
- }
-
-
-
- #region IObjectDefinitionRegistry Members
-
- ///
- /// Returns the
- ///
- /// for the given object name.
- ///
- /// The name of the object to find a definition for.
- ///
- /// The for
- /// the given name (never null).
- ///
- ///
- /// If the object definition cannot be resolved.
- ///
- ///
- /// In case of errors.
- ///
- public override IObjectDefinition GetObjectDefinition(string name)
- {
- return objectFactory.GetObjectDefinition(name);
- }
-
- ///
- /// Register a new object definition with this registry.
- /// Must support
- ///
- /// and .
- ///
- /// The name of the object instance to register.
- /// The definition of the object instance to register.
- ///
- ///
- /// Must support
- /// and
- /// .
- ///
- ///
- ///
- /// If the object definition is invalid.
- ///
- public void RegisterObjectDefinition(string name, IObjectDefinition definition)
- {
- objectFactory.RegisterObjectDefinition(name, definition);
- }
-
- ///
- /// Given a object name, create an alias. We typically use this method to
- /// support names that are illegal within XML ids (used for object names).
- ///
- /// The name of the object.
- /// The alias that will behave the same as the object name.
- ///
- /// If there is no object with the given name.
- ///
- ///
- /// If the alias is already in use.
- ///
- public void RegisterAlias(string name, string theAlias)
- {
- objectFactory.RegisterAlias(name, theAlias);
+ */
+
+#endregion
+
+using System;
+using Spring.Objects.Factory.Config;
+using Spring.Objects.Factory.Support;
+using Spring.Util;
+
+namespace Spring.Context.Support
+{
+ ///
+ /// Generic ApplicationContext implementation that holds a single internal
+ /// instance and does not
+ /// assume a specific object definition format.
+ ///
+ ///
+ /// Implements the interface in order
+ /// to allow for aplying any object definition readers to it.
+ /// Typical usage is to register a variety of object definitions via the
+ /// interface and then call
+ /// to initialize those
+ /// objects with application context semantics (handling
+ /// , auto-detecting
+ /// ObjectFactoryPostProcessors, etc).
+ ///
+ /// In contrast to other IApplicationContext implementations that create a new internal
+ /// IObjectFactory instance for each refresh, the internal IObjectFactory of this context
+ /// is available right from the start, to be able to register object definitions on it.
+ /// may only be called once
+ /// Usage examples
+ ///
+ /// GenericApplicationContext ctx = new GenericApplicationContext();
+ /// // register your objects and object definitions
+ /// ctx.RegisterObjectDefinition(...)
+ /// ctx.Refresh();
+ ///
+ ///
+ /// Mark Pollack
+ public class GenericApplicationContext : AbstractApplicationContext
+ {
+ private readonly DefaultListableObjectFactory objectFactory;
+ private bool refreshed = false;
+
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public GenericApplicationContext()
+ : this(null, true, null, new DefaultListableObjectFactory())
+ {
+ // noop
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// if set to true names in the context are case sensitive.
+ public GenericApplicationContext(bool caseSensitive)
+ : this(null, caseSensitive, null, new DefaultListableObjectFactory())
+ {
+ // noop
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The object factory instance to use for this context.
+ public GenericApplicationContext(DefaultListableObjectFactory objectFactory)
+ : this(null, true, null, objectFactory)
+ {
+ // noop
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The parent application context.
+ public GenericApplicationContext(IApplicationContext parent)
+ : this(null, true, parent, new DefaultListableObjectFactory())
+ {
+ // noop
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name of the application context.
+ /// if set to true names in the context are case sensitive.
+ /// The parent application context.
+ public GenericApplicationContext(string name, bool caseSensitive, IApplicationContext parent)
+ : this(name, caseSensitive, parent, new DefaultListableObjectFactory())
+ {
+ // noop
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The object factory to use for this context
+ /// The parent applicaiton context.
+ public GenericApplicationContext(DefaultListableObjectFactory objectFactory, IApplicationContext parent)
+ : this(null, true, parent, objectFactory)
+ {
+ // noop
+ }
+
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ /// The name of the application context.
+ /// if set to true names in the context are case sensitive.
+ /// The parent application context.
+ /// The object factory to use for this context
+ public GenericApplicationContext(string name, bool caseSensitive, IApplicationContext parent, DefaultListableObjectFactory objectFactory)
+ : base(name, caseSensitive, parent)
+ {
+ AssertUtils.ArgumentNotNull(objectFactory, "objectFactory", "ObjectFactory must not be null");
+ this.objectFactory = objectFactory;
+ this.objectFactory.ParentObjectFactory = base.GetInternalParentObjectFactory();
+ }
+
+ ///
+ /// Do nothing operation. We hold a single internal ObjectFactory and rely on callers
+ /// to register objects throug our public methods (or the ObjectFactory's).
+ ///
+ ///
+ /// In the case of errors encountered while refreshing the object factory.
+ ///
+ protected override void RefreshObjectFactory()
+ {
+ if (refreshed)
+ {
+ throw new InvalidOperationException(
+ "GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
+ }
+
+ refreshed = true;
+ }
+
+ ///
+ /// Return the internal object factory of this application context.
+ ///
+ ///
+ public override IConfigurableListableObjectFactory ObjectFactory
+ {
+ get { return objectFactory; }
+ }
+
+ ///
+ /// Gets the underlying object factory of this context, available for
+ /// registering object definitions.
+ ///
+ /// You need to call Refresh to initialize the
+ /// objects factory and its contained objects with application context
+ /// semantics (autodecting IObjectFactoryPostProcessors, etc).
+ /// The internal object factory (as DefaultListableObjectFactory).
+ public DefaultListableObjectFactory DefaultListableObjectFactory
+ {
+ get { return objectFactory; }
}
///
@@ -258,11 +181,9 @@ namespace Spring.Context.Support
/// i.e. whether there is a local object or alias registered under this name or
/// an inner object created with this name.
///
- public bool IsObjectNameInUse(string objectName)
+ public override bool IsObjectNameInUse(string objectName)
{
return objectFactory.IsObjectNameInUse(objectName);
- }
-
- #endregion
- }
+ }
+ }
}
\ No newline at end of file
diff --git a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs
index f9e01ea1..7c0bbe7e 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Config/IConfigurableObjectFactory.cs
@@ -50,8 +50,8 @@ namespace Spring.Objects.Factory.Config
/// Juergen Hoeller
/// Rick Evans (.NET)
public interface IConfigurableObjectFactory : IHierarchicalObjectFactory, ISingletonObjectRegistry
- {
- ///
+ {
+ ///
/// Set the parent of this object factory.
///
///
diff --git a/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs
index a7affbd2..13a1ed21 100644
--- a/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/IHierarchicalObjectFactory.cs
@@ -47,7 +47,7 @@ namespace Spring.Objects.Factory
///
/// Determines whether the local object factory contains a bean of the given name,
- /// ignoring object defined in ancestor contexts.
+ /// ignoring object defined in ancestor contexts, also resolving a given alias if necessary.
/// This is an alternative to ContainsObject, ignoring an object
/// of the given name from an ancestor object factory.
///
diff --git a/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs
index 6a4e51be..4e07ef16 100644
--- a/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/IListableObjectFactory.cs
@@ -57,8 +57,8 @@ namespace Spring.Objects.Factory
/// Rod Johnson
/// Rick Evans (.NET)
public interface IListableObjectFactory : IObjectFactory
- {
- ///
+ {
+ ///
/// Check if this object factory contains an object definition with the given name.
///
///
diff --git a/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs
index 41ccd8bb..fe3231aa 100644
--- a/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/IObjectFactory.cs
@@ -150,7 +150,12 @@ namespace Spring.Objects.Factory
/// Rick Evans (.NET)
public interface IObjectFactory : IDisposable
{
- ///
+ ///
+ /// Determine whether this object factory treats object names case-sensitive or not.
+ ///
+ bool IsCaseSensitive { get; }
+
+ ///
/// Is this object a singleton?
///
///
@@ -196,8 +201,8 @@ namespace Spring.Objects.Factory
///
///
///
- /// Will ask the parent factory if the object cannot be found in this factory
- /// instance.
+ /// The concrete lookup strategy depends on the implementation. E.g. s
+ /// will also search their parent factory if a name isn't found .
///
///
/// The name of the object to query.
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs
index db9e6331..92875548 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractAutowireCapableObjectFactory.cs
@@ -79,7 +79,7 @@ namespace Spring.Objects.Factory.Support
///
/// The instance for this class.
///
- private readonly ILog log = LogManager.GetLogger(typeof(AbstractAutowireCapableObjectFactory));
+ private readonly ILog log;
#region Constructor (s) / Destructor
@@ -113,6 +113,8 @@ namespace Spring.Objects.Factory.Support
protected AbstractAutowireCapableObjectFactory(bool caseSensitive, IObjectFactory parentFactory)
: base(caseSensitive, parentFactory)
{
+ log = LogManager.GetLogger(this.GetType());
+
this.IgnoreDependencyInterface(typeof(IObjectFactoryAware));
this.IgnoreDependencyInterface(typeof(IObjectNameAware));
}
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs
index 5e6ac00c..800bea15 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectDefinitionReader.cs
@@ -44,10 +44,9 @@ namespace Spring.Objects.Factory.Support
#region Constants
///
- /// The shared instance for this class (and derived classes).
+ /// The instance for this class (and derived classes).
///
- protected static readonly ILog log =
- LogManager.GetLogger(typeof (AbstractObjectDefinitionReader));
+ protected readonly ILog log;
#endregion
@@ -94,6 +93,8 @@ namespace Spring.Objects.Factory.Support
IObjectDefinitionRegistry registry,
AppDomain domain)
{
+ log = LogManager.GetLogger(this.GetType());
+
AssertUtils.ArgumentNotNull(registry, "registry", "IObjectDefinitionRegistry must not be null");
_registry = registry;
_domain = domain;
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
index ad53396b..32e64310 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/AbstractObjectFactory.cs
@@ -89,19 +89,22 @@ namespace Spring.Objects.Factory.Support
///
private static readonly object CURRENTLY_IN_CREATION = new Object();
- ///
- /// The instance for this class.
- ///
- private readonly ILog log = LogManager.GetLogger(typeof(AbstractObjectFactory));
-
///
/// Used as value in hashtable that keeps track of singleton names currently in the
/// process of being created. Would not be necessary if we created a case insensitive implementation of
/// ISet.
///
- private static object emptyObject = new object();
+ private static readonly object emptyObject = new object();
+ ///
+ /// The instance for this class.
+ ///
+ private readonly ILog log;
+ ///
+ /// Cache of singleton objects created by s: FactoryObject name -> product
+ ///
+ private readonly Hashtable factoryObjectProductCache = new Hashtable();
#region Constructor (s) / Destructor
@@ -730,63 +733,128 @@ namespace Spring.Objects.Factory.Support
///
/// The singleton instance of the object.
///
+ [Obsolete("")]
protected internal virtual object GetObjectForInstance(string name, object instance)
{
- //string objectName = TransformedObjectName(name);
+ return GetObjectForInstance(instance, name, TransformedObjectName(name), null);
+ }
+ ///
+ /// Get the object for the given object instance, either the object
+ /// instance itself or its created object in case of an
+ /// .
+ ///
+ /// The object instance.
+ ///
+ /// The name that may include the factory dereference prefix (=the requested name).
+ ///
+ ///
+ /// The canonical object name
+ ///
+ /// the merged object definition
+ ///
+ /// The singleton instance of the object.
+ ///
+ protected internal virtual object GetObjectForInstance(object instance, string name, string canonicalName, RootObjectDefinition rod)
+ {
// don't let calling code try to dereference the
// object factory if the object isn't a factory
- if (IsFactoryDereference(name) && !(instance is IFactoryObject))
+ if (IsFactoryDereference(name) && !(ObjectUtils.IsAssignable(typeof (IFactoryObject), instance)))
{
- throw new ObjectIsNotAFactoryException(TransformedObjectName(name), instance);
+ throw new ObjectIsNotAFactoryException(canonicalName, instance);
}
// now we have the object instance, which may be a normal object
- // or an IFactoryObject. If it's an IFactoryObject, we use it to
- // create an object instance, unless the caller actually wants
- // a reference to the factory.
- if (ObjectUtils.IsAssignableAndNotTransparentProxy(typeof(IFactoryObject), instance))
+ // or an IFactoryObject. If it's an IFactoryObject and the caller wants
+ // a reference to the factory there's nothing more to do
+
+
+ // it's a normal object ?
+ if (!ObjectUtils.IsAssignable(typeof (IFactoryObject), instance))
{
- if (!IsFactoryDereference(name))
+ #region Instrumentation
+
+ if (log.IsDebugEnabled)
{
+ log.Debug(string.Format("Calling code asked for normal instance for name '{0}'.", canonicalName));
+ }
- // return object instance from factory...
- IFactoryObject factory = (IFactoryObject)instance;
- string objectName = TransformedObjectName(name);
+ #endregion
- #region Instrumentation
+ return instance;
+ }
- if (log.IsDebugEnabled)
+ // the user wants the factory itself ?
+ if (!ObjectUtils.IsAssignable(typeof (IFactoryObject), instance) || IsFactoryDereference(name))
+ {
+ #region Instrumentation
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug(
+ string.Format("Calling code asked for IFactoryObject instance for name '{0}'.",
+ TransformedObjectName(name)));
+ }
+
+ #endregion
+
+ return instance;
+ }
+
+ #region Instrumentation
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug(string.Format("Object with name '{0}' is a factory object.", canonicalName));
+ }
+
+ #endregion
+
+ object resultInstance = null;
+
+ if (rod == null)
+ {
+ resultInstance = factoryObjectProductCache[canonicalName];
+ }
+
+ if (resultInstance == null)
+ {
+ // return object instance from factory...
+ IFactoryObject factory = (IFactoryObject) instance;
+
+ if (rod == null && ContainsObjectDefinition(canonicalName))
+ {
+ rod = GetMergedObjectDefinition(canonicalName, true);
+ }
+
+ if (factory.IsSingleton && ContainsSingleton(canonicalName))
+ {
+ lock (factoryObjectProductCache)
{
- log.Debug(string.Format("Object with name '{0}' is a factory object.", objectName));
- }
-
- #endregion
-
- RootObjectDefinition rod =
- (ContainsObjectDefinition(objectName) ? GetMergedObjectDefinition(objectName, true) : null);
- instance = GetObjectFromFactoryObject(factory, objectName, rod);
-
- if (instance == null)
- {
- throw new FactoryObjectNotInitializedException(TransformedObjectName(name),
- "Factory object returned null object - "
- + "possible cause: not fully initialized due to "
- + "circular object reference.");
+ resultInstance = factoryObjectProductCache[canonicalName];
+ if (resultInstance == null)
+ {
+ resultInstance = GetObjectFromFactoryObject(factory, canonicalName, rod);
+ if (resultInstance != null)
+ {
+ factoryObjectProductCache.Add(canonicalName, resultInstance);
+ }
+ return resultInstance;
+ }
}
}
- else
+
+ resultInstance = GetObjectFromFactoryObject(factory, canonicalName, rod);
+
+ if (resultInstance == null)
{
- // the user wants the factory itself...
- if (log.IsDebugEnabled)
- {
- log.Debug(
- string.Format("Calling code asked for IFactoryObject instance for name '{0}'.",
- TransformedObjectName(name)));
- }
+ throw new FactoryObjectNotInitializedException(canonicalName,
+ "Factory object returned null object - "
+ + "possible cause: not fully initialized due to "
+ + "circular object reference.");
}
}
- return instance;
+ return resultInstance;
}
///
@@ -1836,7 +1904,7 @@ namespace Spring.Objects.Factory.Support
#endregion
- instance = GetObjectForInstance(name, sharedInstance);
+ instance = GetObjectForInstance(sharedInstance, name, objectName, null);
return EnsureObjectIsOfRequiredType(name, instance, requiredType);
}
}
@@ -1877,7 +1945,7 @@ namespace Spring.Objects.Factory.Support
{
// create object instance...
object sharedInstance = CreateAndCacheSingletonInstance(objectName, mergedObjectDefinition, arguments);
- instance = GetObjectForInstance(name, sharedInstance);
+ instance = GetObjectForInstance(sharedInstance, name, objectName, mergedObjectDefinition);
}
else
{
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs
index 1081610c..b2bbbb1c 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/ObjectDefinitionValueResolver.cs
@@ -269,7 +269,7 @@ namespace Spring.Objects.Factory.Support
{
//SPRNET-986 ObjectUtils.EmptyObjects -> null
instance = objectFactory.InstantiateObject(actualInnerObjectName, mod, null, false, false);
- result = objectFactory.GetObjectForInstance(actualInnerObjectName, instance);
+ result = objectFactory.GetObjectForInstance(instance, actualInnerObjectName, actualInnerObjectName, mod);
}
catch (ObjectsException ex)
{
diff --git a/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs b/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs
index dad16c3a..cf74e438 100644
--- a/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs
+++ b/src/Spring/Spring.Core/Objects/Factory/Support/StaticListableObjectFactory.cs
@@ -58,6 +58,14 @@ namespace Spring.Objects.Factory.Support
///
private Hashtable objects = new Hashtable();
+ ///
+ /// Determine whether this object factory treats object names case-sensitive or not.
+ ///
+ public bool IsCaseSensitive
+ {
+ get { return true; }
+ }
+
///
/// Return the number of objects defined in the factory.
///
diff --git a/src/Spring/Spring.Core/Util/ObjectUtils.cs b/src/Spring/Spring.Core/Util/ObjectUtils.cs
index 57168af7..154de6d9 100644
--- a/src/Spring/Spring.Core/Util/ObjectUtils.cs
+++ b/src/Spring/Spring.Core/Util/ObjectUtils.cs
@@ -25,6 +25,7 @@ using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Runtime.Remoting;
+using System.Runtime.Remoting.Proxies;
using Common.Logging;
using Spring.Objects;
using Spring.Reflection.Dynamic;
@@ -311,8 +312,32 @@ namespace Spring.Util
/// True if the type is assignable from the value.
public static bool IsAssignable(Type type, object obj)
{
+ AssertUtils.ArgumentNotNull(type, "type");
+ if (!type.IsPrimitive && obj == null)
+ {
+ return true;
+ }
+
+ if (RemotingServices.IsTransparentProxy(obj))
+ {
+ RealProxy rp = RemotingServices.GetRealProxy(obj);
+ if (rp is IRemotingTypeInfo)
+ {
+ return ((IRemotingTypeInfo) rp).CanCastTo(type, obj);
+ }
+ else if (rp != null)
+ {
+ type = rp.GetProxiedType();
+ }
+
+ if (type == null)
+ {
+ // cannot decide
+ return false;
+ }
+ }
+
return (type.IsInstanceOfType(obj) ||
- (!type.IsPrimitive && obj == null) ||
(type.Equals(typeof(bool)) && obj is Boolean) ||
(type.Equals(typeof(byte)) && obj is Byte) ||
(type.Equals(typeof(char)) && obj is Char) ||
diff --git a/src/Spring/Spring.Web/Context/Support/WebApplicationContext.cs b/src/Spring/Spring.Web/Context/Support/WebApplicationContext.cs
index 2d93b0f2..7e7491e9 100644
--- a/src/Spring/Spring.Web/Context/Support/WebApplicationContext.cs
+++ b/src/Spring/Spring.Web/Context/Support/WebApplicationContext.cs
@@ -57,11 +57,6 @@ namespace Spring.Context.Support
/// Aleksandar Seovic
public class WebApplicationContext : AbstractXmlApplicationContext
{
- ///
- /// The instance for this class.
- ///
- private static readonly ILog log = LogManager.GetLogger(typeof(WebApplicationContext));
-
// holds construction info for debugging output
private DateTime _constructionTimeStamp;
private string _constructionUrl;
@@ -133,6 +128,8 @@ namespace Spring.Context.Support
static WebApplicationContext()
{
+ ILog s_weblog = LogManager.GetLogger(typeof(WebApplicationContext));
+
// register for ContextRegistry.Cleared event - we need to discard our cache in this case
ContextRegistry.Cleared += new EventHandler(OnContextRegistryCleared);
@@ -153,23 +150,23 @@ namespace Spring.Context.Support
typeof(HttpRuntime).GetField("_beforeFirstRequest", BindingFlags.Instance | BindingFlags.NonPublic).
GetValue(runtime);
}
- log.Debug("BeforeFirstRequest:" + beforeFirstRequest);
+ s_weblog.Debug("BeforeFirstRequest:" + beforeFirstRequest);
if (beforeFirstRequest)
{
try
{
string firstRequestPath = HttpRuntime.AppDomainAppVirtualPath.TrimEnd('/') + "/dummy.context";
- log.Info("Forcing first request " + firstRequestPath);
+ s_weblog.Info("Forcing first request " + firstRequestPath);
SafeMethod fnProcessRequestNow = new SafeMethod(typeof(HttpRuntime).GetMethod("ProcessRequestNow", BindingFlags.Static|BindingFlags.NonPublic));
SimpleWorkerRequest wr = new SimpleWorkerRequest(firstRequestPath, string.Empty, new StringWriter());
fnProcessRequestNow.Invoke(null, new object[] { wr });
// HttpRuntime.ProcessRequest(
// wr);
- log.Info("Successfully processed first request!");
+ s_weblog.Info("Successfully processed first request!");
}
catch (Exception ex)
{
- log.Error("Failed processing first request", ex);
+ s_weblog.Error("Failed processing first request", ex);
throw;
}
}
@@ -184,9 +181,10 @@ namespace Spring.Context.Support
{
lock (s_webContextCache)
{
- if (log.IsDebugEnabled)
+ ILog s_weblog = LogManager.GetLogger(typeof(WebApplicationContext));
+ if (s_weblog.IsDebugEnabled)
{
- log.Debug("received ContextRegistry.Cleared event - clearing webContextCache");
+ s_weblog.Debug("received ContextRegistry.Cleared event - clearing webContextCache");
}
s_webContextCache.Clear();
}
@@ -229,20 +227,23 @@ namespace Spring.Context.Support
contextName = DefaultRootContextName;
}
+ ILog s_weblog = LogManager.GetLogger(typeof(WebApplicationContext));
+ bool isLogDebugEnabled = s_weblog.IsDebugEnabled;
+
lock (s_webContextCache)
{
- if (log.IsDebugEnabled)
+ if (isLogDebugEnabled)
{
- log.Debug(string.Format("looking up web context '{0}' in WebContextCache", contextName));
+ s_weblog.Debug(string.Format("looking up web context '{0}' in WebContextCache", contextName));
}
// first lookup in our own cache
IApplicationContext context = (IApplicationContext) s_webContextCache[contextName];
if (context != null)
{
// found - nothing to do anymore
- if (log.IsDebugEnabled)
+ if (isLogDebugEnabled)
{
- log.Debug(
+ s_weblog.Debug(
string.Format("returning WebContextCache hit '{0}' for vpath '{1}' ", context, contextName));
}
return context;
@@ -251,9 +252,9 @@ namespace Spring.Context.Support
// lookup ContextRegistry
lock (ContextRegistry.SyncRoot)
{
- if (log.IsDebugEnabled)
+ if (isLogDebugEnabled)
{
- log.Debug(string.Format("looking up web context '{0}' in ContextRegistry", contextName));
+ s_weblog.Debug(string.Format("looking up web context '{0}' in ContextRegistry", contextName));
}
if (ContextRegistry.IsContextRegistered(contextName))
@@ -266,9 +267,9 @@ namespace Spring.Context.Support
// finally ask HttpConfigurationSystem for the requested context
try
{
- if (log.IsDebugEnabled)
+ if (isLogDebugEnabled)
{
- log.Debug(
+ s_weblog.Debug(
string.Format(
"web context for vpath '{0}' not found. Force creation using filepath '{1}'",
contextName, virtualPath));
@@ -282,20 +283,20 @@ namespace Spring.Context.Support
if (context != null)
{
- if (log.IsDebugEnabled)
- log.Debug(string.Format("got context '{0}' for vpath '{1}'", context, contextName));
+ if (isLogDebugEnabled)
+ s_weblog.Debug(string.Format("got context '{0}' for vpath '{1}'", context, contextName));
}
else
{
- if (log.IsDebugEnabled)
- log.Debug(string.Format("no context defined for vpath '{0}'", contextName));
+ if (isLogDebugEnabled)
+ s_weblog.Debug(string.Format("no context defined for vpath '{0}'", contextName));
}
}
catch (Exception ex)
{
- if (log.IsErrorEnabled)
+ if (s_weblog.IsErrorEnabled)
{
- log.Error(string.Format("failed creating context '{0}'", contextName), ex);
+ s_weblog.Error(string.Format("failed creating context '{0}'", contextName), ex);
}
#if NET_1_1
if (ConfigurationUtils.IsConfigurationException(ex))
@@ -314,9 +315,9 @@ namespace Spring.Context.Support
// add it to the cache
// Note: use 'contextName' not 'context.Name' here - the same context may be used for different paths!
s_webContextCache.Add(contextName, context);
- if (log.IsDebugEnabled)
+ if (isLogDebugEnabled)
{
- log.Debug(
+ s_weblog.Debug(
string.Format("added context '{0}' to WebContextCache for vpath '{1}'", context, contextName));
}
@@ -329,9 +330,9 @@ namespace Spring.Context.Support
if (!s_webContextCache.ContainsKey(parentContext.Name))
{
s_webContextCache.Add(parentContext.Name, parentContext);
- if (log.IsDebugEnabled)
+ if (isLogDebugEnabled)
{
- log.Debug(
+ s_weblog.Debug(
string.Format("added parent context '{0}' to WebContextCache for vpath '{1}'",
parentContext, parentContext.Name));
}
@@ -369,7 +370,7 @@ namespace Spring.Context.Support
protected override DefaultListableObjectFactory CreateObjectFactory()
{
string contextPath = GetContextPathWithTrailingSlash();
- return new WebObjectFactory(contextPath, this.CaseSensitive, GetInternalParentObjectFactory());
+ return new WebObjectFactory(contextPath, this.IsCaseSensitive, GetInternalParentObjectFactory());
}
///
diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs
index b473843d..7fec7558 100644
--- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs
+++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/AdvisorAutoProxyCreatorCircularReferencesTests.cs
@@ -22,6 +22,7 @@
using System;
using System.Reflection;
+using Common.Logging;
using NUnit.Framework;
using Spring.Aop.Framework.DynamicProxy;
using Spring.Aop.Support;
@@ -45,23 +46,67 @@ namespace Spring.Aop.Framework.AutoProxy
public void TestAutoProxyCreation()
{
XmlApplicationContext context = new XmlApplicationContext(ReadOnlyXmlTestResource.GetFilePath("advisorAutoProxyCreatorCircularReferencesTests.xml", typeof(AdvisorAutoProxyCreatorCircularReferencesTests)));
+ CountingAfterReturningAdvisor countingAdvisor = (CountingAfterReturningAdvisor)context.GetObject("testAdvisor");
+
// direct deps of AutoProxyCreator are not eligable for proxying
Assert.IsFalse(AopUtils.IsAopProxy(context.GetObject("aapc")));
- Assert.IsFalse(AopUtils.IsAopProxy(context.GetObject("testAdvisor")));
- Assert.IsFalse(AopUtils.IsAopProxy(context.GetObject("&testObjectFactory")));
+ Assert.IsFalse(AopUtils.IsAopProxy(countingAdvisor));
+
+ TestObjectFactoryObject testObjectFactory = (TestObjectFactoryObject) context.GetObject("&testObjectFactory");
+ Assert.IsFalse(AopUtils.IsAopProxy(testObjectFactory));
+
Assert.IsFalse(AopUtils.IsAopProxy(context.GetObject("someOtherObject")));
// this one is completely independent
Assert.IsTrue(AopUtils.IsAopProxy(context.GetObject("independentObject")));
- // products of the factory created at runtime should be proxied
- Assert.IsFalse(AopUtils.IsAopProxy(context.GetObject("testObjectFactory")));
+
+ // Asserts SPRNET-1225 - advisor dependencies most not be auto-proxied
+ object testObject = context.GetObject("testObjectFactory");
+ Assert.IsFalse(AopUtils.IsAopProxy(testObject));
+
+ // Asserts SPRNET-1224 - factory product most be cached
+ context.GetObject("testObjectFactory");
+ testObjectFactory.GetObjectCounter = 0;
+ context.GetObject("testObjectFactory");
+ Assert.AreEqual(0, testObjectFactory.GetObjectCounter);
+
+ ICloneable someOtherObject = (ICloneable) context.GetObject("someOtherObject");
+ someOtherObject.Clone();
+ ICloneable independentObject = (ICloneable) context.GetObject("independentObject");
+ independentObject.Clone();
+ Assert.AreEqual(1, countingAdvisor.GetCalls());
}
}
#region Support Classes
- public class TestAdvisor : StaticMethodMatcherPointcutAdvisor
+ public class TestDefaultAdvisorAutoProxyCreator : DefaultAdvisorAutoProxyCreator, IInitializingObject
+ {
+ private readonly ILog _logger;
+
+ public TestDefaultAdvisorAutoProxyCreator()
+ {
+ _logger = LogManager.GetLogger(this.GetType().Name + "#" + GetHashCode());
+ _logger.Trace("Created instance");
+ }
+
+ protected override object[] GetAdvicesAndAdvisorsForObject(Type targetType, string targetName, ITargetSource customTargetSource)
+ {
+ _logger.Trace("GetAdvicesAndAdvisorsForObject begin");
+ object[] advices = base.GetAdvicesAndAdvisorsForObject(targetType, targetName, customTargetSource);
+ _logger.Trace("GetAdvicesAndAdvisorsForObject end");
+ return advices;
+ }
+
+ public override void AfterPropertiesSet()
+ {
+ _logger.Trace("AfterPropertiesSet");
+ base.AfterPropertiesSet();
+ }
+ }
+
+ public class CountingAfterReturningAdvisor : StaticMethodMatcherPointcutAdvisor
{
private ITestObject testObject;
@@ -71,26 +116,62 @@ namespace Spring.Aop.Framework.AutoProxy
set { this.testObject = value; }
}
+ public int GetCalls()
+ {
+ return ((CountingAfterReturningAdvice) base.Advice).GetCalls();
+ }
+
+ public CountingAfterReturningAdvisor()
+ {
+ LogManager.GetLogger(this.GetType()).Trace("Created instance #" + this.GetHashCode());
+ base.Advice = new CountingAfterReturningAdvice();
+ }
+
public override bool Matches(MethodInfo method, Type targetType)
{
return true;
}
}
- public class SomeOtherObject
- {}
+ public class SomeOtherObject : ICloneable
+ {
+ public SomeOtherObject()
+ {
+ LogManager.GetLogger(this.GetType()).Trace("Created instance #" + this.GetHashCode());
+ }
- public class IndependentObject
- { }
+ public object Clone()
+ {
+ return this;
+ }
+ }
+
+ public class IndependentObject : ICloneable
+ {
+ public IndependentObject()
+ {
+ LogManager.GetLogger(this.GetType()).Trace("Created instance #" + this.GetHashCode());
+ }
+
+ public object Clone()
+ {
+ return this;
+ }
+ }
public class TestObjectFactoryObject : IFactoryObject, IInitializingObject
{
private bool initialized = false;
private ITestObject testObject;
private SomeOtherObject someOtherObject;
+ private readonly ILog _logger;
+
+ public int GetObjectCounter = 0;
public TestObjectFactoryObject()
{
+ _logger = LogManager.GetLogger(this.GetType().Name + "#" + this.GetHashCode());
+ _logger.Trace("Created instance");
}
public SomeOtherObject SomeOtherObject
@@ -101,15 +182,15 @@ namespace Spring.Aop.Framework.AutoProxy
public object GetObject()
{
+ GetObjectCounter++;
// return product only, if factory has been fully initialized!
if (!initialized)
{
+ _logger.Trace("GetObject(): not initialized, returning null");
return null;
}
- else
- {
- return testObject;
- }
+ _logger.Trace("GetObject(): initialized, returning testObject");
+ return testObject;
}
public Type ObjectType
@@ -119,12 +200,11 @@ namespace Spring.Aop.Framework.AutoProxy
// return type only if we are ready to deliver our product!
if (!initialized)
{
+ _logger.Trace("get_ObjectType(): not initialized, returning null");
return null;
}
- else
- {
- return typeof(ITestObject);
- }
+ _logger.Trace("get_ObjectType(): initialized, returning typeof(ITestObject)");
+ return typeof(ITestObject);
}
}
@@ -135,6 +215,7 @@ namespace Spring.Aop.Framework.AutoProxy
public void AfterPropertiesSet()
{
+ _logger.Trace("AfterPropertiesSet");
Assert.IsNotNull(someOtherObject);
testObject = new TestObject();
initialized = true;
diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/advisorAutoProxyCreatorCircularReferencesTests.xml b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/advisorAutoProxyCreatorCircularReferencesTests.xml
index a3ec4d4e..2c12e6dc 100644
--- a/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/advisorAutoProxyCreatorCircularReferencesTests.xml
+++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/AutoProxy/advisorAutoProxyCreatorCircularReferencesTests.xml
@@ -2,22 +2,23 @@
Reproduces a problem with AutoProxyCreators, IFactoryObjects,
circular dependencies and a certain order of object definitions
-
+
-
-
+
+
-
+
\ No newline at end of file
diff --git a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs
index ec6dcc7d..953b5490 100644
--- a/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs
+++ b/test/Spring/Spring.Aop.Tests/Aop/Framework/ProxyFactoryObjectTests.cs
@@ -243,9 +243,10 @@ namespace Spring.Aop.Framework
}
///
- /// Must see effect immediately on behaviour.
+ /// Must see effect immediately on behaviour.
+ /// TODO (EE): Note that we can't add or remove interfaces without reconfiguring the singleton.
///
- [Test]
+ [Test, Ignore("change according to ProxyFactoryBeanTests.canAddAndRemoveAdvicesOnSingleton")]
public void CanAddAndRemoveIntroductionsOnSingleton()
{
try
diff --git a/test/Spring/Spring.Core.Tests/CommonTypes.cs b/test/Spring/Spring.Core.Tests/CommonTypes.cs
index b13b9e26..5ad0ce54 100644
--- a/test/Spring/Spring.Core.Tests/CommonTypes.cs
+++ b/test/Spring/Spring.Core.Tests/CommonTypes.cs
@@ -128,7 +128,12 @@ namespace Spring
#region IObjectFactory Members
- public object this[string name]
+ public bool IsCaseSensitive
+ {
+ get { return true; }
+ }
+
+ public object this[string name]
{
get { return null; }
}
@@ -216,7 +221,13 @@ namespace Spring
#region IObjectFactory Members
- public object this[string name]
+ public bool IsCaseSensitive
+ {
+ get { innerExecute();
+ return true; }
+ }
+
+ public object this[string name]
{
get
{
diff --git a/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs b/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs
index 1bec58e6..bb7eb564 100644
--- a/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs
+++ b/test/Spring/Spring.Core.Tests/Context/CommonTypes.cs
@@ -263,6 +263,11 @@ namespace Spring.Context
// factory.AddObjectPostProcessor(new ApplicationContextAwareProcessor(this));
}
+ public override bool IsObjectNameInUse(string objectName)
+ {
+ return factory.IsObjectNameInUse(objectName);
+ }
+
public override IConfigurableListableObjectFactory ObjectFactory
{
get { return factory; }
@@ -416,7 +421,12 @@ namespace Spring.Context
#region IObjectFactory Members
- public object this[string name]
+ public bool IsCaseSensitive
+ {
+ get { return true; }
+ }
+
+ public object this[string name]
{
get { return null; }
}
diff --git a/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs
index adf2e81f..96d227b9 100644
--- a/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs
+++ b/test/Spring/Spring.Core.Tests/Context/Support/ApplicationObjectSupportTests.cs
@@ -158,7 +158,12 @@ namespace Spring.Context.Support
#region IObjectFactory Members
- public object this[string name]
+ public bool IsCaseSensitive
+ {
+ get { return true; }
+ }
+
+ public object this[string name]
{
get { return null; }
}
diff --git a/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests.cs b/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests.cs
index 40c98aeb..ae046ac2 100644
--- a/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests.cs
+++ b/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests.cs
@@ -26,8 +26,10 @@ using System.Reflection;
using NUnit.Framework;
using Spring.Aop.Config;
+using Spring.Aop.Framework.AutoProxy;
using Spring.Context;
using Spring.Context.Support;
+using Spring.Core.IO;
using Spring.Objects;
using Spring.Objects.Factory.Support;
using Spring.Objects.Factory.Xml;
@@ -40,6 +42,31 @@ namespace Spring.Transaction.Config
[TestFixture]
public class TxNamespaceParserTests
{
+ private class ResourceXmlApplicationContext : AbstractXmlApplicationContext
+ {
+ private readonly IResource[] configurationResources;
+ public ResourceXmlApplicationContext(params IResource[] configurationResources)
+ : base()
+ {
+ this.configurationResources = configurationResources;
+ }
+
+ protected override void LoadObjectDefinitions(XmlObjectDefinitionReader objectDefinitionReader)
+ {
+ base.LoadObjectDefinitions(objectDefinitionReader);
+ objectDefinitionReader.LoadObjectDefinitions(configurationResources);
+ }
+
+ protected override string[] ConfigurationLocations
+ {
+ get { return null; }
+ }
+ }
+
+ private const string APPCTXCFG_PROLOG = @"";
+ private const string APPCTXCFG_START = APPCTXCFG_PROLOG + @"";
+ private const string APPCTXCFG_END = @"";
+
private IApplicationContext ctx;
[SetUp]
@@ -50,6 +77,19 @@ namespace Spring.Transaction.Config
ctx = new XmlApplicationContext("assembly://Spring.Data.Tests/Spring.Transaction.Config/TxNamespaceParserTests.xml");
}
+ [Test]
+ public void AppliesTxAttributeDrivenAttributes()
+ {
+ StringResource appCtxCfg = new StringResource(
+ APPCTXCFG_START
+ + ""
+ + APPCTXCFG_END);
+
+ IApplicationContext appCtx = new ResourceXmlApplicationContext(appCtxCfg);
+// DefaultAdvisorAutoProxyCreator daapc = (DefaultAdvisorAutoProxyCreator) appCtx.GetObject(AopNamespaceUtils.AUTO_PROXY_CREATOR_OBJECT_NAME);
+// Assert.AreEqual(2, daapc.Order);
+ }
+
[Test]
public void Registered()
{
diff --git a/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests_TxAttributeDriven.xml b/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests_TxAttributeDriven.xml
new file mode 100644
index 00000000..90123b20
--- /dev/null
+++ b/test/Spring/Spring.Data.Tests/Transaction/Config/TxNamespaceParserTests_TxAttributeDriven.xml
@@ -0,0 +1,4 @@
+
+
+
+
diff --git a/test/Spring/Spring.Messaging.Nms.Tests/Messaging/Nms/Connections/TestMessageConsumer.cs b/test/Spring/Spring.Messaging.Nms.Tests/Messaging/Nms/Connections/TestMessageConsumer.cs
index 357af79f..54c8bc6f 100644
--- a/test/Spring/Spring.Messaging.Nms.Tests/Messaging/Nms/Connections/TestMessageConsumer.cs
+++ b/test/Spring/Spring.Messaging.Nms.Tests/Messaging/Nms/Connections/TestMessageConsumer.cs
@@ -25,9 +25,14 @@ namespace Spring.Messaging.Nms.Connections
{
public class TestMessageConsumer : IMessageConsumer
{
-
public event MessageListener Listener;
+ private void InvokeListener(IMessage message)
+ {
+ MessageListener listener = Listener;
+ if (listener != null) listener(message);
+ }
+
public IMessage Receive()
{
throw new NotImplementedException();
diff --git a/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.2008.csproj b/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.2008.csproj
index 6d4d918d..fd64add6 100644
--- a/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.2008.csproj
+++ b/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.2008.csproj
@@ -46,10 +46,6 @@
False..\..\..\lib\Net\2.0\Common.Logging.dll
-
- False
- ..\..\..\lib\Net\2.0\Common.Logging.Log4Net.dll
- False..\..\..\lib\Net\2.0\log4net.dll
diff --git a/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.dll.config b/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.dll.config
index bbaa7231..8d7d63c5 100644
--- a/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.dll.config
+++ b/test/Spring/Spring.Messaging.Nms.Tests/Spring.Messaging.Nms.Tests.dll.config
@@ -32,12 +32,17 @@ limitations under the License.
+
+
+
+
diff --git a/test/Spring/Spring.Messaging.Tests/Spring.Messaging.Tests.2008.csproj b/test/Spring/Spring.Messaging.Tests/Spring.Messaging.Tests.2008.csproj
index fd28387e..3312e1c1 100644
--- a/test/Spring/Spring.Messaging.Tests/Spring.Messaging.Tests.2008.csproj
+++ b/test/Spring/Spring.Messaging.Tests/Spring.Messaging.Tests.2008.csproj
@@ -2,7 +2,7 @@
DebugAnyCPU
- 9.0.21022
+ 9.0.307292.0{41BC3AEA-7EB3-48BF-B1EC-84119376AC98}Library
@@ -33,10 +33,6 @@
False..\..\..\lib\Net\2.0\Common.Logging.dll
-
- False
- ..\..\..\lib\Net\2.0\Common.Logging.Log4Net.dll
- False..\..\..\lib\Net\2.0\log4net.dll