Fix thread race conditions when automatically registering components with Castle Windsor #16

Closed
wants to merge 3 commits into
from
Jump to file or symbol
Failed to load files and symbols.
+50 −29
Diff settings

Always

Just for now

@@ -28,6 +28,7 @@ namespace OpenRasta.DI.Windsor
public class WindsorDependencyResolver : DependencyResolverCore, IDependencyResolver
{
readonly IWindsorContainer _windsorContainer;
+ static readonly object _containerLock = new object();
public WindsorDependencyResolver(IWindsorContainer container)
{
@@ -83,26 +84,37 @@ protected override IEnumerable<TService> ResolveAllCore<TService>()
protected override void AddDependencyCore(Type dependent, Type concrete, DependencyLifetime lifetime)
{
string componentName = Guid.NewGuid().ToString();
- if (lifetime != DependencyLifetime.PerRequest)
+ lock (_containerLock)
{
+ if (lifetime != DependencyLifetime.PerRequest)
+ {
#if CASTLE_20
- _windsorContainer.AddComponentLifeStyle(componentName, dependent, concrete,
- ConvertLifestyles.ToLifestyleType(lifetime));
+ _windsorContainer.Register(
+ Component
+ .For(dependent)
+ .ImplementedBy(concrete)
+ .Named(componentName)
+ .LifeStyle.Is(ConvertLifestyles.ToLifestyleType(lifetime)));
#elif CASTLE_10
- _windsorContainer.AddComponentWithLifestyle(componentName, dependent, concrete, ConvertLifestyles.ToLifestyleType(lifetime));
+ _windsorContainer.AddComponentWithLifestyle(componentName, dependent, concrete, ConvertLifestyles.ToLifestyleType(lifetime));
#endif
- }
- else
- {
+ }
+ else
+ {
#if CASTLE_20
- _windsorContainer.Register(
- Component.For(dependent).Named(componentName).ImplementedBy(concrete).LifeStyle.Custom(typeof (ContextStoreLifetime)));
+ _windsorContainer.Register(
+ Component
+ .For(dependent)
+ .Named(componentName)
+ .ImplementedBy(concrete)
+ .LifeStyle.Custom(typeof(ContextStoreLifetime)));
#elif CASTLE_10
- ComponentModel component = _windsorContainer.Kernel.ComponentModelBuilder.BuildModel(componentName, dependent, concrete, null);
- component.LifestyleType = ConvertLifestyles.ToLifestyleType(lifetime);
- component.CustomLifestyle = typeof (ContextStoreLifetime);
- _windsorContainer.Kernel.AddCustomComponent(component);
+ ComponentModel component = _windsorContainer.Kernel.ComponentModelBuilder.BuildModel(componentName, dependent, concrete, null);
+ component.LifestyleType = ConvertLifestyles.ToLifestyleType(lifetime);
+ component.CustomLifestyle = typeof(ContextStoreLifetime);
+ _windsorContainer.Kernel.AddCustomComponent(component);
#endif
+ }
}
}
@@ -111,9 +123,28 @@ protected override void AddDependencyInstanceCore(Type serviceType, object insta
string key = Guid.NewGuid().ToString();
if (lifetime == DependencyLifetime.PerRequest)
{
- // try to see if we have a registration already
var store = (IContextStore) Resolve(typeof (IContextStore));
- if (_windsorContainer.Kernel.HasComponent(serviceType))
+ // try to see if we have a registration already
+ if (_windsorContainer.Kernel.HasComponent(serviceType) == false)
+ {
+ lock (_containerLock)
+ {
+ if (_windsorContainer.Kernel.HasComponent(serviceType) == false)
+ {
+ var component = new ComponentModel(key, serviceType, instance.GetType());
+ var customLifestyle = typeof(ContextStoreLifetime);
+ component.LifestyleType = LifestyleType.Custom;
+ component.CustomLifestyle = customLifestyle;
+ component.CustomComponentActivator = typeof(ContextStoreInstanceActivator);
+ component.ExtendedProperties[Constants.REG_IS_INSTANCE_KEY] = true;
+ component.Name = component.Name;
+
+ _windsorContainer.Kernel.AddCustomComponent(component);
+ store[component.Name] = instance;
+ }
+ }
+ }
+ else
{
var handler = _windsorContainer.Kernel.GetHandler(serviceType);
if (handler.ComponentModel.ExtendedProperties[Constants.REG_IS_INSTANCE_KEY] != null)
@@ -126,23 +157,13 @@ protected override void AddDependencyInstanceCore(Type serviceType, object insta
throw new DependencyResolutionException("Cannot register an instance for a type already registered");
}
}
- else
- {
- var component = new ComponentModel(key, serviceType, instance.GetType());
- var customLifestyle = typeof (ContextStoreLifetime);
- component.LifestyleType = LifestyleType.Custom;
- component.CustomLifestyle = customLifestyle;
- component.CustomComponentActivator = typeof (ContextStoreInstanceActivator);
- component.ExtendedProperties[Constants.REG_IS_INSTANCE_KEY] = true;
- component.Name = component.Name;
-
- _windsorContainer.Kernel.AddCustomComponent(component);
- store[component.Name] = instance;
- }
}
else if (lifetime == DependencyLifetime.Singleton)
{
- _windsorContainer.Kernel.AddComponentInstance(key, serviceType, instance);
+ lock (_containerLock)
+ {
+ _windsorContainer.Kernel.AddComponentInstance(key, serviceType, instance);
+ }
}
}