From 713875080df9e0273764668ffc8bbccc502317a5 Mon Sep 17 00:00:00 2001 From: Steve Bohlen Date: Thu, 29 Jan 2015 19:56:12 -0500 Subject: [PATCH] introduce method to block interaction with internal ObjectFactory instance when ApplicationContext isn't in a valid state to respond (e.g., while starting up, shutting down, or being disposed) --- .../Support/AbstractApplicationContext.cs | 111 ++++++++++++------ 1 file changed, 72 insertions(+), 39 deletions(-) diff --git a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs index 57776920..aee15098 100644 --- a/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs +++ b/src/Spring/Spring.Core/Context/Support/AbstractApplicationContext.cs @@ -147,10 +147,28 @@ namespace Spring.Context.Support private DateTime _startupDate; private readonly bool _isCaseSensitive; private EventRaiser _eventRaiser; + private bool _isInDispose; + private bool _isInStart; + private bool _isInStop; #endregion + /// + /// Protects access to the internal object factory used by the ApplicationContext if attempted to be accessed when in improper state. + /// + /// The internal ObjectFactory used by the ApplicationContext + /// Cannot Access ApplicationContext in this state! + private IConfigurableListableObjectFactory SafeGetObjectFactory() + { + if (_isInStart || _isInStop || _isInDispose) + { + throw new InvalidOperationException("Cannot Access ApplicationContext in this state!"); + } + + return ObjectFactory; + } + #region Constructor (s) / Destructor /// @@ -234,6 +252,8 @@ namespace Spring.Context.Support /// public virtual void Dispose() { + _isInDispose = true; + GC.SuppressFinalize(this); #region Instrumentation @@ -253,6 +273,8 @@ namespace Spring.Context.Support PublishEvent(this, new ContextClosedEventArgs()); ObjectFactory.Dispose(); + + _isInDispose = false; } #endregion @@ -566,7 +588,7 @@ namespace Spring.Context.Support } else if (IsTypeMatch(processorName, typeof(IPriorityOrdered))) { - priorityOrderedFactoryProcessors.Add(ObjectFactory.GetObject(processorName)); + priorityOrderedFactoryProcessors.Add(SafeGetObjectFactory().GetObject(processorName)); } else if (IsTypeMatch(processorName, typeof(IOrdered))) { @@ -584,18 +606,18 @@ namespace Spring.Context.Support List orderedFactoryProcessors = new List(); foreach (string orderedFactoryProcessorsName in orderedFactoryProcessorsNames) { - orderedFactoryProcessors.Add(ObjectFactory.GetObject(orderedFactoryProcessorsName)); + orderedFactoryProcessors.Add(SafeGetObjectFactory().GetObject(orderedFactoryProcessorsName)); } orderedFactoryProcessors.Sort(new OrderComparator()); - InvokeObjectFactoryPostProcessors(orderedFactoryProcessors, ObjectFactory); + InvokeObjectFactoryPostProcessors(orderedFactoryProcessors, SafeGetObjectFactory()); // and then the unordered ones... List nonOrderedPostProcessors = new List(); foreach (string nonOrderedFactoryProcessorName in nonOrderedFactoryProcessorNames) { - nonOrderedPostProcessors.Add(ObjectFactory.GetObject(nonOrderedFactoryProcessorName)); + nonOrderedPostProcessors.Add(SafeGetObjectFactory().GetObject(nonOrderedFactoryProcessorName)); } - InvokeObjectFactoryPostProcessors(nonOrderedPostProcessors, ObjectFactory); + InvokeObjectFactoryPostProcessors(nonOrderedPostProcessors, SafeGetObjectFactory()); #region Instrumentation @@ -614,7 +636,7 @@ namespace Spring.Context.Support protected virtual void InvokePriorityOrderedObjectFactoryPostProcessors(List factoryProcessorNames, List priorityOrderedFactoryProcessors) { priorityOrderedFactoryProcessors.Sort(new OrderComparator()); - InvokeObjectFactoryPostProcessors(priorityOrderedFactoryProcessors, ObjectFactory); + InvokeObjectFactoryPostProcessors(priorityOrderedFactoryProcessors, SafeGetObjectFactory()); // Now will find any additional IObjectFactoryPostProcessors that implement IPriorityOrdered that may have been // resolved due to using TypeAlias @@ -626,13 +648,13 @@ namespace Spring.Context.Support { if (IsTypeMatch(factoryProcessorName, typeof(IPriorityOrdered))) { - priorityOrderedFactoryProcessors.Add(ObjectFactory.GetObject(factoryProcessorName)); + priorityOrderedFactoryProcessors.Add(SafeGetObjectFactory().GetObject(factoryProcessorName)); } } } // Second, invoke newly discovered IObjectFactoryPostProcessors that implement IPriorityOrdered. priorityOrderedFactoryProcessors.Sort(new OrderComparator()); - InvokeObjectFactoryPostProcessors(priorityOrderedFactoryProcessors, ObjectFactory); + InvokeObjectFactoryPostProcessors(priorityOrderedFactoryProcessors, SafeGetObjectFactory()); } private void InvokeObjectFactoryPostProcessors(IList objectFactoryPostProcessors, IConfigurableListableObjectFactory objectFactory) @@ -651,7 +673,7 @@ namespace Spring.Context.Support // objectProcessors.Sort(new OrderComparator()); foreach (IObjectPostProcessor objectPostProcessor in objectProcessors) { - ObjectFactory.AddObjectPostProcessor(objectPostProcessor); + SafeGetObjectFactory().AddObjectPostProcessor(objectPostProcessor); } if (log.IsDebugEnabled) @@ -673,7 +695,7 @@ namespace Spring.Context.Support private void RefreshObjectPostProcessorChecker(IConfigurableListableObjectFactory objectFactory) { int registeredObjectPostProcessorCount = GetObjectNamesForType(typeof(IObjectPostProcessor), true, false).Count; - int objectPostProcessorCount = ObjectFactory.ObjectPostProcessorCount + 1 + int objectPostProcessorCount = SafeGetObjectFactory().ObjectPostProcessorCount + 1 + registeredObjectPostProcessorCount; ((ObjectPostProcessorChecker)_defaultObjectPostProcessors[0]).Reset(objectFactory, objectPostProcessorCount); } @@ -820,7 +842,7 @@ namespace Spring.Context.Support { _messageSource = new DelegatingMessageSource( GetInternalParentMessageSource()); - ObjectFactory.RegisterSingleton(MessageSourceObjectName, _messageSource); + SafeGetObjectFactory().RegisterSingleton(MessageSourceObjectName, _messageSource); #region Instrumentation @@ -836,7 +858,7 @@ namespace Spring.Context.Support else { _messageSource = new StaticMessageSource(); - ObjectFactory.RegisterSingleton(MessageSourceObjectName, _messageSource); + SafeGetObjectFactory().RegisterSingleton(MessageSourceObjectName, _messageSource); #region Instrumentation @@ -1082,6 +1104,8 @@ namespace Spring.Context.Support /// public void Start() { + _isInStart = true; + IDictionary lifecycleObjects = LifeCycleObjects; foreach (KeyValuePair dictionaryEntry in lifecycleObjects) { @@ -1095,6 +1119,8 @@ namespace Spring.Context.Support } } } + + _isInStart = false; } /// @@ -1107,6 +1133,8 @@ namespace Spring.Context.Support /// public void Stop() { + _isInStop = true; + IDictionary lifecycleObjects = LifeCycleObjects; foreach (KeyValuePair dictionaryEntry in lifecycleObjects) { @@ -1120,6 +1148,8 @@ namespace Spring.Context.Support } } } + + _isInStop = false; } /// @@ -1231,7 +1261,7 @@ namespace Spring.Context.Support /// public IList GetObjectNamesForType(Type type) { - return ObjectFactory.GetObjectNamesForType(type); + return SafeGetObjectFactory().GetObjectNamesForType(type); } /// @@ -1285,7 +1315,7 @@ namespace Spring.Context.Support /// public IList GetObjectNamesForType(Type type, bool includePrototypes, bool includeFactoryObjects) { - return ObjectFactory.GetObjectNamesForType(type, includePrototypes, includeFactoryObjects); + return SafeGetObjectFactory().GetObjectNamesForType(type, includePrototypes, includeFactoryObjects); } /// @@ -1352,7 +1382,7 @@ namespace Spring.Context.Support /// public IList GetObjectDefinitionNames(bool includeAncestors) { - return ObjectFactory.GetObjectDefinitionNames(includeAncestors); + return SafeGetObjectFactory().GetObjectDefinitionNames(includeAncestors); } /// @@ -1374,7 +1404,7 @@ namespace Spring.Context.Support /// public virtual IObjectDefinition GetObjectDefinition(string name) { - return ObjectFactory.GetObjectDefinition(name); + return SafeGetObjectFactory().GetObjectDefinition(name); } @@ -1398,7 +1428,7 @@ namespace Spring.Context.Support /// public IObjectDefinition GetObjectDefinition(string name, bool includeAncestors) { - return ObjectFactory.GetObjectDefinition(name, includeAncestors); + return SafeGetObjectFactory().GetObjectDefinition(name, includeAncestors); } /// @@ -1454,7 +1484,7 @@ namespace Spring.Context.Support /// public IDictionary GetObjects() { - return ObjectFactory.GetObjects(true, true); + return SafeGetObjectFactory().GetObjects(true, true); } /// @@ -1487,7 +1517,7 @@ namespace Spring.Context.Support public IDictionary GetObjectsOfType( Type type, bool includePrototypes, bool includeFactoryObjects) { - return ObjectFactory.GetObjectsOfType(type, includePrototypes, includeFactoryObjects); + return SafeGetObjectFactory().GetObjectsOfType(type, includePrototypes, includeFactoryObjects); } /// @@ -1518,7 +1548,7 @@ namespace Spring.Context.Support /// public IDictionary GetObjects(bool includePrototypes, bool includeFactoryObjects) { - return ObjectFactory.GetObjects(includePrototypes, includeFactoryObjects); + return SafeGetObjectFactory().GetObjects(includePrototypes, includeFactoryObjects); } /// @@ -1575,7 +1605,7 @@ namespace Spring.Context.Support /// public int ObjectDefinitionCount { - get { return ObjectFactory.ObjectDefinitionCount; } + get { return SafeGetObjectFactory().ObjectDefinitionCount; } } /// @@ -1588,7 +1618,7 @@ namespace Spring.Context.Support /// public bool ContainsObjectDefinition(string name) { - return ObjectFactory.ContainsObjectDefinition(name); + return SafeGetObjectFactory().ContainsObjectDefinition(name); } #endregion @@ -1609,7 +1639,10 @@ namespace Spring.Context.Support /// public object this[string name] { - get { return ObjectFactory.GetObject(name); } + get + { + return SafeGetObjectFactory().GetObject(name); + } } /// @@ -1622,7 +1655,7 @@ namespace Spring.Context.Support /// public bool ContainsObject(string name) { - return ObjectFactory.ContainsObject(name); + return SafeGetObjectFactory().ContainsObject(name); } /// @@ -1636,7 +1669,7 @@ namespace Spring.Context.Support /// public IList GetAliases(string name) { - return ObjectFactory.GetAliases(name); + return SafeGetObjectFactory().GetAliases(name); } @@ -1696,7 +1729,7 @@ namespace Spring.Context.Support /// public object CreateObject(string name, Type requiredType, object[] arguments) { - return ObjectFactory.CreateObject(name, requiredType, arguments); + return SafeGetObjectFactory().CreateObject(name, requiredType, arguments); } /// @@ -1760,7 +1793,7 @@ namespace Spring.Context.Support /// public object GetObject(string name, Type requiredType) { - return ObjectFactory.GetObject(name, requiredType); + return SafeGetObjectFactory().GetObject(name, requiredType); } /// @@ -1777,7 +1810,7 @@ namespace Spring.Context.Support /// public object GetObject(string name) { - return ObjectFactory.GetObject(name); + return SafeGetObjectFactory().GetObject(name); } /// @@ -1852,7 +1885,7 @@ namespace Spring.Context.Support /// public object GetObject(string name, object[] arguments) { - return ObjectFactory.GetObject(name, arguments); + return SafeGetObjectFactory().GetObject(name, arguments); } /// @@ -1930,7 +1963,7 @@ namespace Spring.Context.Support /// public object GetObject(string name, Type requiredType, object[] arguments) { - return ObjectFactory.GetObject(name, requiredType, arguments); + return SafeGetObjectFactory().GetObject(name, requiredType, arguments); } /// @@ -1944,7 +1977,7 @@ namespace Spring.Context.Support /// public bool IsSingleton(string name) { - return ObjectFactory.IsSingleton(name); + return SafeGetObjectFactory().IsSingleton(name); } /// @@ -1966,7 +1999,7 @@ namespace Spring.Context.Support /// if there is no object with the given name. public bool IsPrototype(string name) { - return ObjectFactory.IsPrototype(name); + return SafeGetObjectFactory().IsPrototype(name); } @@ -1988,7 +2021,7 @@ namespace Spring.Context.Support /// public bool IsTypeMatch(string name, Type targetType) { - return ObjectFactory.IsTypeMatch(name, targetType); + return SafeGetObjectFactory().IsTypeMatch(name, targetType); } /// @@ -2003,7 +2036,7 @@ namespace Spring.Context.Support /// public Type GetType(string name) { - return ObjectFactory.GetType(name); + return SafeGetObjectFactory().GetType(name); } /// @@ -2020,7 +2053,7 @@ namespace Spring.Context.Support /// public object ConfigureObject(object target, string name) { - return ObjectFactory.ConfigureObject(target, name); + return SafeGetObjectFactory().ConfigureObject(target, name); } /// @@ -2040,7 +2073,7 @@ namespace Spring.Context.Support /// public object ConfigureObject(object target, string name, IObjectDefinition definition) { - return ObjectFactory.ConfigureObject(target, name, definition); + return SafeGetObjectFactory().ConfigureObject(target, name, definition); } #endregion @@ -2074,7 +2107,7 @@ namespace Spring.Context.Support /// public bool ContainsLocalObject(string name) { - return ObjectFactory.ContainsLocalObject(name); + return SafeGetObjectFactory().ContainsLocalObject(name); } #endregion @@ -2111,7 +2144,7 @@ namespace Spring.Context.Support /// public virtual void RegisterObjectDefinition(string name, IObjectDefinition definition) { - ObjectFactory.RegisterObjectDefinition(name, definition); + SafeGetObjectFactory().RegisterObjectDefinition(name, definition); } /// @@ -2128,7 +2161,7 @@ namespace Spring.Context.Support /// public virtual void RegisterAlias(string name, string theAlias) { - ObjectFactory.RegisterAlias(name, theAlias); + SafeGetObjectFactory().RegisterAlias(name, theAlias); } #endregion