diff --git a/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs b/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs
index 0f4047b9..96e74c39 100644
--- a/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs
+++ b/src/Spring/Spring.Core/Context/Support/ContextRegistry.cs
@@ -1,285 +1,286 @@
-#region License
-
-/*
- * Copyright © 2002-2005 the original author or authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#endregion
-
-#region Imports
-
-using System;
-using System.Collections;
-using System.Collections.Specialized;
-using System.Configuration;
-using Common.Logging;
-
-using Spring.Util;
-
-#endregion
-
-namespace Spring.Context.Support
-{
- ///
- /// Provides access to a central registry of
- /// s.
- ///
- ///
- ///
- /// A singleton implementation to access one or more application contexts. Application
- /// context instances are cached.
- ///
- /// Note that the use of this class or similar is unnecessary except (sometimes) for
- /// a small amount of glue code. Excessive usage will lead to code that is more tightly
- /// coupled, and harder to modify or test. Consider refactoring your code to use standard
- /// Dependency Injection techniques or implement the interface IApplicationContextAware to
- /// obtain a reference to an application context.
- ///
- /// Mark Pollack
- /// Aleksandar Seovic
- ///
- public sealed class ContextRegistry
- {
- ///
- /// The shared instance for this class (and derived classes).
- ///
- private static readonly ILog log = LogManager.GetLogger(typeof(ContextRegistry));
-
- private static readonly object syncRoot = new Object();
- private static readonly ContextRegistry instance = new ContextRegistry();
- private static string rootContextName = null;
-
- private IDictionary contextMap = CollectionsUtil.CreateCaseInsensitiveHashtable();
-
- #region Constructor (s) / Destructor
-
- // CLOVER:OFF
-
- ///
- /// Creates a new instance of the ContextRegistry class.
- ///
- ///
- ///
- /// Explicit static constructor to tell C# compiler
- /// not to mark type as beforefieldinit.
- ///
- ///
- static ContextRegistry()
- {}
-
- // CLOVER:ON
-
- #endregion
-
- ///
- /// This event is fired, if ContextRegistry.Clear() is called.
- /// Clients may register to get informed
- ///
- ///
- /// This event is fired while still holding a lock on the Registry.
- /// 'sender' parameter is sent as typeof(ContextRegistry), EventArgs are not used
- ///
- public static event EventHandler Cleared;
-
- ///
- /// Gets an object that should be used to synchronize access to ContextRegistry
- /// from the calling code.
- ///
- public static object SyncRoot
- {
- get { return syncRoot; }
- }
-
- ///
- /// Registers an instance of an
- /// .
- ///
- ///
- ///
- /// This is usually called via a
- /// inside a .NET
- /// application configuration file.
- ///
- ///
- /// The application context to be registered.
- ///
- /// If a context has previously been registered using the same name
- ///
- public static void RegisterContext(IApplicationContext context)
- {
- lock (syncRoot)
- {
- if (instance.contextMap.Contains(context.Name))
- {
- IApplicationContext ctx = (IApplicationContext)instance.contextMap[context.Name];
- throw new ApplicationContextException(
- string.Format("Existing context '{0}' already registered under name '{1}'.",
- ctx, context.Name));
- }
- instance.contextMap[context.Name] = context;
-
- #region Instrumentation
-
- if (log.IsDebugEnabled)
- {
- log.Debug(String.Format(
- "Registering context '{0}' under name '{1}'.", context, context.Name));
- }
-
- #endregion
-
- if (rootContextName == null)
- {
- rootContextName = context.Name;
- }
- }
- }
-
- ///
- /// Returns the root application context.
- ///
- ///
- ///
- /// The first call to GetContext will create the context
- /// as specified in the .NET application configuration file
- /// under the location spring/context.
- ///
- ///
- /// The root application context.
- public static IApplicationContext GetContext()
- {
- lock (syncRoot)
- {
- InitializeContextIfNeeded();
- return GetContext(rootContextName);
- }
- }
-
- ///
- /// Returns context based on specified name.
- ///
- ///
- ///
- /// The first call to GetContext will create the context
- /// as specified in the .NET application configuration file
- /// under the location spring/context.
- ///
- ///
- /// The context name.
- /// The specified context, or null, if context with that name doesn't exists.
- ///
- /// If the context name is null or empty
- ///
- public static IApplicationContext GetContext(string name)
- {
- if (StringUtils.IsNullOrEmpty(name))
- {
- throw new ArgumentException(
- "The context name passed to the GetContext method cannot be null or empty.");
- }
- else
- {
- lock (syncRoot)
- {
- InitializeContextIfNeeded();
- IApplicationContext ctx = (IApplicationContext)instance.contextMap[name];
-
- #region Instrumentation
-
- if (log.IsDebugEnabled)
- {
- if (ctx == null)
- {
- log.Debug(String.Format(
- "No context registered under name '{0}'.", name));
- }
- else
- {
- log.Debug(String.Format(
- "Returning context '{0}' registered under name '{1}'.", ctx, name));
- }
- }
-
- #endregion
-
- return ctx;
- }
- }
- }
-
- ///
- /// Removes all registered
- /// s from this
- /// registry.
- ///
- ///
- /// Raises the event while still holding a lock on
- ///
- public static void Clear()
- {
- lock (syncRoot)
- {
- foreach (IApplicationContext ctx in instance.contextMap.Values)
- {
- ctx.Dispose();
- }
- instance.contextMap.Clear();
- rootContextName = null;
- ConfigurationUtils.RefreshSection(AbstractApplicationContext.ContextSectionName);
- if (Cleared != null)
- {
- Cleared(typeof(ContextRegistry), EventArgs.Empty);
- }
- }
- }
-
- ///
- /// Allows to check, if a context is already registered
- ///
- /// The context name.
- /// true, if the context is already registered. false otherwise
- public static bool IsContextRegistered( string name )
- {
- lock (instance)
- {
- return (instance.contextMap[name] != null);
- }
- }
-
- private static bool rootContextCurrentlyInCreation;
-
- private static void InitializeContextIfNeeded()
- {
- if (rootContextName == null)
- {
- if (rootContextCurrentlyInCreation)
- {
- throw new InvalidOperationException("root context is currently in creation. You must not call ContextRegistry.GetContext() from e.g. constructors of your singleton objects");
- }
-
- rootContextCurrentlyInCreation = true;
- try
- {
- ConfigurationUtils.GetSection(AbstractApplicationContext.ContextSectionName);
- }
- finally
- {
- rootContextCurrentlyInCreation = false;
- }
- }
- }
- }
-}
-
+#region License
+
+/*
+ * Copyright © 2002-2005 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#endregion
+
+#region Imports
+
+using System;
+using System.Collections;
+using System.Collections.Specialized;
+using System.Configuration;
+using Common.Logging;
+
+using Spring.Util;
+
+#endregion
+
+namespace Spring.Context.Support
+{
+ ///
+ /// Provides access to a central registry of
+ /// s.
+ ///
+ ///
+ ///
+ /// A singleton implementation to access one or more application contexts. Application
+ /// context instances are cached.
+ ///
+ /// Note that the use of this class or similar is unnecessary except (sometimes) for
+ /// a small amount of glue code. Excessive usage will lead to code that is more tightly
+ /// coupled, and harder to modify or test. Consider refactoring your code to use standard
+ /// Dependency Injection techniques or implement the interface IApplicationContextAware to
+ /// obtain a reference to an application context.
+ ///
+ /// Mark Pollack
+ /// Aleksandar Seovic
+ ///
+ public sealed class ContextRegistry
+ {
+ ///
+ /// The shared instance for this class (and derived classes).
+ ///
+ private static readonly ILog log = LogManager.GetLogger(typeof(ContextRegistry));
+
+ private static readonly object syncRoot = new Object();
+ private static readonly ContextRegistry instance = new ContextRegistry();
+ private static string rootContextName = null;
+
+ private IDictionary contextMap = CollectionsUtil.CreateCaseInsensitiveHashtable();
+
+ #region Constructor (s) / Destructor
+
+ // CLOVER:OFF
+
+ ///
+ /// Creates a new instance of the ContextRegistry class.
+ ///
+ ///
+ ///
+ /// Explicit static constructor to tell C# compiler
+ /// not to mark type as beforefieldinit.
+ ///
+ ///
+ static ContextRegistry()
+ {}
+
+ // CLOVER:ON
+
+ #endregion
+
+ ///
+ /// This event is fired, if ContextRegistry.Clear() is called.
+ /// Clients may register to get informed
+ ///
+ ///
+ /// This event is fired while still holding a lock on the Registry.
+ /// 'sender' parameter is sent as typeof(ContextRegistry), EventArgs are not used
+ ///
+ public static event EventHandler Cleared;
+
+ ///
+ /// Gets an object that should be used to synchronize access to ContextRegistry
+ /// from the calling code.
+ ///
+ public static object SyncRoot
+ {
+ get { return syncRoot; }
+ }
+
+ ///
+ /// Registers an instance of an
+ /// .
+ ///
+ ///
+ ///
+ /// This is usually called via a
+ /// inside a .NET
+ /// application configuration file.
+ ///
+ ///
+ /// The application context to be registered.
+ ///
+ /// If a context has previously been registered using the same name
+ ///
+ public static void RegisterContext(IApplicationContext context)
+ {
+ lock (syncRoot)
+ {
+ if (instance.contextMap.Contains(context.Name))
+ {
+ IApplicationContext ctx = (IApplicationContext)instance.contextMap[context.Name];
+ throw new ApplicationContextException(
+ string.Format("Existing context '{0}' already registered under name '{1}'.",
+ ctx, context.Name));
+ }
+ instance.contextMap[context.Name] = context;
+
+ #region Instrumentation
+
+ if (log.IsDebugEnabled)
+ {
+ log.Debug(String.Format(
+ "Registering context '{0}' under name '{1}'.", context, context.Name));
+ }
+
+ #endregion
+
+ if (rootContextName == null)
+ {
+ rootContextName = context.Name;
+ }
+ }
+ }
+
+ ///
+ /// Returns the root application context.
+ ///
+ ///
+ ///
+ /// The first call to GetContext will create the context
+ /// as specified in the .NET application configuration file
+ /// under the location spring/context.
+ ///
+ ///
+ /// The root application context.
+ public static IApplicationContext GetContext()
+ {
+ lock (syncRoot)
+ {
+ InitializeContextIfNeeded();
+ return GetContext(rootContextName);
+ }
+ }
+
+ ///
+ /// Returns context based on specified name.
+ ///
+ ///
+ ///
+ /// The first call to GetContext will create the context
+ /// as specified in the .NET application configuration file
+ /// under the location spring/context.
+ ///
+ ///
+ /// The context name.
+ /// The specified context, or null, if context with that name doesn't exists.
+ ///
+ /// If the context name is null or empty
+ ///
+ public static IApplicationContext GetContext(string name)
+ {
+ if (StringUtils.IsNullOrEmpty(name))
+ {
+ throw new ArgumentException(
+ "The context name passed to the GetContext method cannot be null or empty.");
+ }
+ else
+ {
+ lock (syncRoot)
+ {
+ InitializeContextIfNeeded();
+ IApplicationContext ctx = (IApplicationContext)instance.contextMap[name];
+
+ #region Instrumentation
+
+ if (log.IsDebugEnabled)
+ {
+ if (ctx == null)
+ {
+ log.Debug(String.Format(
+ "No context registered under name '{0}'.", name));
+ }
+ else
+ {
+ log.Debug(String.Format(
+ "Returning context '{0}' registered under name '{1}'.", ctx, name));
+ }
+ }
+
+ #endregion
+
+ return ctx;
+ }
+ }
+ }
+
+ ///
+ /// Removes all registered
+ /// s from this
+ /// registry.
+ ///
+ ///
+ /// Raises the event while still holding a lock on
+ ///
+ public static void Clear()
+ {
+ lock (syncRoot)
+ {
+ foreach (IApplicationContext ctx in instance.contextMap.Values)
+ {
+ ctx.Dispose();
+ }
+ instance.contextMap.Clear();
+ rootContextName = null;
+ ConfigurationUtils.RefreshSection(AbstractApplicationContext.ContextSectionName);
+ DynamicCodeManager.Clear();
+ if (Cleared != null)
+ {
+ Cleared(typeof(ContextRegistry), EventArgs.Empty);
+ }
+ }
+ }
+
+ ///
+ /// Allows to check, if a context is already registered
+ ///
+ /// The context name.
+ /// true, if the context is already registered. false otherwise
+ public static bool IsContextRegistered( string name )
+ {
+ lock (instance)
+ {
+ return (instance.contextMap[name] != null);
+ }
+ }
+
+ private static bool rootContextCurrentlyInCreation;
+
+ private static void InitializeContextIfNeeded()
+ {
+ if (rootContextName == null)
+ {
+ if (rootContextCurrentlyInCreation)
+ {
+ throw new InvalidOperationException("root context is currently in creation. You must not call ContextRegistry.GetContext() from e.g. constructors of your singleton objects");
+ }
+
+ rootContextCurrentlyInCreation = true;
+ try
+ {
+ ConfigurationUtils.GetSection(AbstractApplicationContext.ContextSectionName);
+ }
+ finally
+ {
+ rootContextCurrentlyInCreation = false;
+ }
+ }
+ }
+ }
+}
+
diff --git a/src/Spring/Spring.Core/Util/DynamicCodeManager.cs b/src/Spring/Spring.Core/Util/DynamicCodeManager.cs
index 6ed6aac9..c19e9092 100644
--- a/src/Spring/Spring.Core/Util/DynamicCodeManager.cs
+++ b/src/Spring/Spring.Core/Util/DynamicCodeManager.cs
@@ -140,5 +140,16 @@ namespace Spring.Util
AssemblyBuilder assembly = (AssemblyBuilder) module.Assembly;
assembly.Save(assembly.GetName().Name + ".dll");
}
+
+ ///
+ /// Removes all registered s.
+ ///
+ public static void Clear()
+ {
+ lock (s_moduleCache.SyncRoot)
+ {
+ s_moduleCache.Clear();
+ }
+ }
}
}
\ No newline at end of file
diff --git a/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs b/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs
index 369d635c..89e8df81 100644
--- a/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs
+++ b/test/Spring/Spring.Core.Tests/Context/Support/ContextRegistryTests.cs
@@ -22,8 +22,13 @@
using System;
using System.Xml;
+
using NUnit.Framework;
+using Spring.Objects;
+using Spring.Proxy;
+using Spring.Objects.Factory.Support;
+
#endregion
namespace Spring.Context.Support
@@ -41,7 +46,6 @@ namespace Spring.Context.Support
ContextRegistry.Clear();
}
-
///
/// This handler simulates calls to ContextRegistry during context creation
///
@@ -130,6 +134,36 @@ namespace Spring.Context.Support
Assert.IsNull(context,
"Named context is not null even though a context has not been registered under the lookup name.");
}
+
+ [Test]
+ public void ClearWithDynamicProxies()
+ {
+ CompositionProxyTypeBuilder typeBuilder = new CompositionProxyTypeBuilder();
+ typeBuilder.TargetType = typeof(TestObject);
+ Type proxyType = typeBuilder.BuildProxyType();
+
+ XmlApplicationContext ctx1 = new XmlApplicationContext();
+ RootObjectDefinition od1 = new RootObjectDefinition(proxyType, false);
+ od1.PropertyValues.Add("Name", "Bruno");
+ ((DefaultListableObjectFactory)ctx1.ObjectFactory).RegisterObjectDefinition("testObject", od1);
+ ContextRegistry.RegisterContext(ctx1);
+
+ ITestObject to1 = ContextRegistry.GetContext().GetObject("testObject") as ITestObject;
+ Assert.IsNotNull(to1);
+ Assert.AreEqual("Bruno", to1.Name);
+
+ XmlApplicationContext ctx2 = new XmlApplicationContext();
+ RootObjectDefinition od2 = new RootObjectDefinition(proxyType, false);
+ od2.PropertyValues.Add("Name", "Baia");
+ ((DefaultListableObjectFactory)ctx2.ObjectFactory).RegisterObjectDefinition("testObject", od2);
+
+ ContextRegistry.Clear();
+
+ ITestObject to2 = ctx2.GetObject("testObject") as ITestObject;
+ Assert.IsNotNull(to2);
+ Assert.AreEqual("Baia", to2.Name);
+ }
+
#if NET_2_0
// TODO : Add support for .NET 1.x
[Test]