Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/aspnetwebstack.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/System.Json/JsonValue.cs21
-rw-r--r--src/System.Web.Http.SelfHost/Channels/HttpMessageEncoderFactory.cs17
-rw-r--r--src/System.Web.Http.SelfHost/Channels/HttpMessageEncodingRequestContext.cs15
-rw-r--r--src/System.Web.Http.SelfHost/ServiceModel/Activation/AspNetEnvironment.cs60
-rw-r--r--src/System.Web.Http.SelfHost/ServiceModel/Channels/AsyncResult.cs23
-rw-r--r--src/System.Web.Http.SelfHost/System.Web.Http.SelfHost.csproj1
-rw-r--r--src/System.Web.Http/Controllers/HttpActionDescriptor.cs31
-rw-r--r--src/System.Web.Http/Dispatcher/DefaultHttpControllerFactory.cs53
-rw-r--r--src/System.Web.Http/HttpServer.cs29
-rw-r--r--src/System.Web.Mvc/Async/TaskAsyncActionDescriptor.cs3
-rw-r--r--src/System.Web.Mvc/ControllerTypeCache.cs2
-rw-r--r--src/System.Web.Mvc/MultiServiceResolver.cs18
-rw-r--r--src/System.Web.Mvc/SingleServiceResolver.cs32
-rw-r--r--src/System.Web.Mvc/UrlRewriterHelper.cs2
14 files changed, 88 insertions, 219 deletions
diff --git a/src/System.Json/JsonValue.cs b/src/System.Json/JsonValue.cs
index 7c41d677..f4d0b3fc 100644
--- a/src/System.Json/JsonValue.cs
+++ b/src/System.Json/JsonValue.cs
@@ -21,10 +21,7 @@ namespace System.Json
[DataContract]
public class JsonValue : IEnumerable<KeyValuePair<string, JsonValue>>, IDynamicMetaObjectProvider
{
- private static object lockKey = new object();
-
- // Double-checked locking pattern requires volatile for read/write synchronization
- private static volatile JsonValue defaultInstance;
+ private static JsonValue defaultInstance = new JsonValue();
private int changingListenersCount;
private int changedListenersCount;
@@ -130,21 +127,7 @@ namespace System.Json
/// </summary>
private static JsonValue DefaultInstance
{
- get
- {
- if (defaultInstance == null)
- {
- lock (lockKey)
- {
- if (defaultInstance == null)
- {
- defaultInstance = new JsonValue();
- }
- }
- }
-
- return defaultInstance;
- }
+ get { return defaultInstance; }
}
/// <summary>
diff --git a/src/System.Web.Http.SelfHost/Channels/HttpMessageEncoderFactory.cs b/src/System.Web.Http.SelfHost/Channels/HttpMessageEncoderFactory.cs
index 15c0354d..75627968 100644
--- a/src/System.Web.Http.SelfHost/Channels/HttpMessageEncoderFactory.cs
+++ b/src/System.Web.Http.SelfHost/Channels/HttpMessageEncoderFactory.cs
@@ -4,6 +4,7 @@ using System.IO;
using System.Net.Http;
using System.ServiceModel;
using System.ServiceModel.Channels;
+using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.SelfHost.Properties;
using System.Web.Http.SelfHost.ServiceModel.Channels;
@@ -230,10 +231,8 @@ namespace System.Web.Http.SelfHost.Channels
private class ByteArrayBufferManagerContent : ByteArrayContent
{
- private bool _disposed;
private BufferManager _bufferManager;
private byte[] _content;
- private object _disposingLock;
public ByteArrayBufferManagerContent(BufferManager bufferManager, byte[] content, int offset, int count)
: base(content, offset, count)
@@ -242,23 +241,19 @@ namespace System.Web.Http.SelfHost.Channels
_bufferManager = bufferManager;
_content = content;
- _disposingLock = new object();
}
protected override void Dispose(bool disposing)
{
try
{
- if (disposing && !_disposed)
+ if (disposing)
{
- lock (_disposingLock)
+ BufferManager oldBufferManager = Interlocked.Exchange(ref _bufferManager, null);
+ if (oldBufferManager != null)
{
- if (!_disposed)
- {
- _disposed = true;
- _bufferManager.ReturnBuffer(_content);
- _content = null;
- }
+ oldBufferManager.ReturnBuffer(_content);
+ _content = null;
}
}
}
diff --git a/src/System.Web.Http.SelfHost/Channels/HttpMessageEncodingRequestContext.cs b/src/System.Web.Http.SelfHost/Channels/HttpMessageEncodingRequestContext.cs
index 33aaf3d4..9e9f5d14 100644
--- a/src/System.Web.Http.SelfHost/Channels/HttpMessageEncodingRequestContext.cs
+++ b/src/System.Web.Http.SelfHost/Channels/HttpMessageEncodingRequestContext.cs
@@ -17,14 +17,11 @@ namespace System.Web.Http.SelfHost.Channels
private RequestContext _innerContext;
private Message _configuredRequestMessage;
- private bool _isRequestConfigured;
- private object _requestConfigurationLock;
public HttpMessageEncodingRequestContext(RequestContext innerContext)
{
Contract.Assert(innerContext != null, "The 'innerContext' parameter should not be null.");
_innerContext = innerContext;
- _requestConfigurationLock = new object();
}
internal Exception Exception { get; set; }
@@ -35,17 +32,9 @@ namespace System.Web.Http.SelfHost.Channels
{
get
{
- if (!_isRequestConfigured)
+ if (_configuredRequestMessage == null)
{
- lock (_requestConfigurationLock)
- {
- if (!_isRequestConfigured)
- {
- Message innerMessage = _innerContext.RequestMessage;
- _configuredRequestMessage = ConfigureRequestMessage(innerMessage);
- _isRequestConfigured = true;
- }
- }
+ _configuredRequestMessage = ConfigureRequestMessage(_innerContext.RequestMessage);
}
return _configuredRequestMessage;
diff --git a/src/System.Web.Http.SelfHost/ServiceModel/Activation/AspNetEnvironment.cs b/src/System.Web.Http.SelfHost/ServiceModel/Activation/AspNetEnvironment.cs
deleted file mode 100644
index 14f4f24d..00000000
--- a/src/System.Web.Http.SelfHost/ServiceModel/Activation/AspNetEnvironment.cs
+++ /dev/null
@@ -1,60 +0,0 @@
-using System.Configuration;
-using System.Diagnostics.CodeAnalysis;
-using System.ServiceModel.Channels;
-
-namespace System.Web.Http.SelfHost.ServiceModel.Activation
-{
- internal class AspNetEnvironment
- {
- public const string HostingMessagePropertyName = "webhost";
-
- private const string HostingMessagePropertyTypeName = "System.ServiceModel.Activation.HostingMessageProperty";
- private static AspNetEnvironment _current;
- private static readonly object _thisLock = new object();
-
- public static AspNetEnvironment Current
- {
- get
- {
- if (_current == null)
- {
- lock (_thisLock)
- {
- if (_current == null)
- {
- _current = new AspNetEnvironment();
- }
- }
- }
-
- return _current;
- }
- }
-
- // ALTERED_FOR_PORT:
- // The GetHostingProperty() code below is an altered implementation from the System.ServiceModel.Activation.HostedAspNetEnvironment class.
- // The original implementation casts the hostingProperty to type System.ServiceModel.Activation.HostingMessageProperty. However,
- // this class is internal sealed, therefore we simply check the type name.
- [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This is existing public API")]
- public object GetHostingProperty(Message message)
- {
- object hostingProperty;
- if (message.Properties.TryGetValue(HostingMessagePropertyName, out hostingProperty))
- {
- string hostingPropertyName = hostingProperty.GetType().FullName;
- if (String.Equals(hostingPropertyName, HostingMessagePropertyTypeName, System.StringComparison.Ordinal))
- {
- return hostingProperty;
- }
- }
-
- return null;
- }
-
- [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "This is existing public API")]
- public object GetConfigurationSection(string sectionPath)
- {
- return ConfigurationManager.GetSection(sectionPath);
- }
- }
-}
diff --git a/src/System.Web.Http.SelfHost/ServiceModel/Channels/AsyncResult.cs b/src/System.Web.Http.SelfHost/ServiceModel/Channels/AsyncResult.cs
index cbf0ce88..ba1c07c3 100644
--- a/src/System.Web.Http.SelfHost/ServiceModel/Channels/AsyncResult.cs
+++ b/src/System.Web.Http.SelfHost/ServiceModel/Channels/AsyncResult.cs
@@ -11,25 +11,22 @@ namespace System.Web.Http.SelfHost.ServiceModel.Channels
internal abstract class AsyncResult : IAsyncResult
{
private static AsyncCallback _asyncCompletionWrapperCallback;
- private AsyncCallback _completionCallback;
+ private readonly AsyncCallback _completionCallback;
private bool _completedSynchronously;
private bool _endCalled;
private Exception _exception;
private bool _isCompleted;
private AsyncCompletion _nextAsyncCompletion;
- private object _state;
+ private readonly object _state;
private Action _beforePrepareAsyncCompletionAction;
private Func<IAsyncResult, bool> _checkSyncValidationFunc;
-
private ManualResetEvent _manualResetEvent;
-
- private readonly object _thisLock;
+ private readonly object _manualResetEventLock = new object();
protected AsyncResult(AsyncCallback callback, object state)
{
_completionCallback = callback;
_state = state;
- _thisLock = new object();
}
/// <summary>
@@ -49,12 +46,7 @@ namespace System.Web.Http.SelfHost.ServiceModel.Channels
{
get
{
- if (_manualResetEvent != null)
- {
- return _manualResetEvent;
- }
-
- lock (ThisLock)
+ lock (_manualResetEventLock)
{
if (_manualResetEvent == null)
{
@@ -84,11 +76,6 @@ namespace System.Web.Http.SelfHost.ServiceModel.Channels
// used in conjunction with PrepareAsyncCompletion to allow for finally blocks
protected Action<AsyncResult, Exception> OnCompleting { get; set; }
- private object ThisLock
- {
- get { return _thisLock; }
- }
-
// subclasses like TraceAsyncResult can use this to wrap the callback functionality in a scope
protected Action<AsyncCallback, IAsyncResult> VirtualCallback { get; set; }
@@ -123,7 +110,7 @@ namespace System.Web.Http.SelfHost.ServiceModel.Channels
}
else
{
- lock (ThisLock)
+ lock (_manualResetEventLock)
{
_isCompleted = true;
if (_manualResetEvent != null)
diff --git a/src/System.Web.Http.SelfHost/System.Web.Http.SelfHost.csproj b/src/System.Web.Http.SelfHost/System.Web.Http.SelfHost.csproj
index bed689c7..36520358 100644
--- a/src/System.Web.Http.SelfHost/System.Web.Http.SelfHost.csproj
+++ b/src/System.Web.Http.SelfHost/System.Web.Http.SelfHost.csproj
@@ -99,7 +99,6 @@
<Compile Include="Channels\HttpBindingSecurityModeHelper.cs" />
<Compile Include="HttpSelfHostConfiguration.cs" />
<Compile Include="HttpSelfHostServer.cs" />
- <Compile Include="ServiceModel\Activation\AspNetEnvironment.cs" />
<Compile Include="ServiceModel\Channels\AsyncResult.cs" />
<Compile Include="ServiceModel\Channels\BufferedOutputStream.cs" />
<Compile Include="ServiceModel\Channels\BufferManagerOutputStream.cs" />
diff --git a/src/System.Web.Http/Controllers/HttpActionDescriptor.cs b/src/System.Web.Http/Controllers/HttpActionDescriptor.cs
index 83f7c067..f65354db 100644
--- a/src/System.Web.Http/Controllers/HttpActionDescriptor.cs
+++ b/src/System.Web.Http/Controllers/HttpActionDescriptor.cs
@@ -17,8 +17,7 @@ namespace System.Web.Http.Controllers
private readonly ConcurrentDictionary<object, object> _properties = new ConcurrentDictionary<object, object>();
private IActionResultConverter _converter;
- private readonly object _thisLock = new object();
- private Collection<FilterInfo> _filterPipeline;
+ private readonly Lazy<Collection<FilterInfo>> _filterPipeline;
private HttpConfiguration _configuration;
private HttpControllerDescriptor _controllerDescriptor;
@@ -28,9 +27,11 @@ namespace System.Web.Http.Controllers
protected HttpActionDescriptor()
{
+ _filterPipeline = new Lazy<Collection<FilterInfo>>(InitializeFilterPipeline);
}
protected HttpActionDescriptor(HttpControllerDescriptor controllerDescriptor)
+ : this()
{
if (controllerDescriptor == null)
{
@@ -197,26 +198,20 @@ namespace System.Web.Http.Controllers
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Filter pipeline can be built dynamically")]
public virtual Collection<FilterInfo> GetFilterPipeline()
{
- if (_filterPipeline == null)
- {
- lock (_thisLock)
- {
- if (_filterPipeline == null)
- {
- IEnumerable<IFilterProvider> filterProviders = _configuration.ServiceResolver.GetFilterProviders();
+ return _filterPipeline.Value;
+ }
- IEnumerable<FilterInfo> filters = filterProviders.SelectMany(fp => fp.GetFilters(_configuration, this)).OrderBy(f => f, FilterInfoComparer.Instance);
+ private Collection<FilterInfo> InitializeFilterPipeline()
+ {
+ IEnumerable<IFilterProvider> filterProviders = _configuration.ServiceResolver.GetFilterProviders();
- // Need to discard duplicate filters from the end, so that most specific ones get kept (Action scope) and
- // less specific ones get removed (Global)
- filters = RemoveDuplicates(filters.Reverse()).Reverse();
+ IEnumerable<FilterInfo> filters = filterProviders.SelectMany(fp => fp.GetFilters(_configuration, this)).OrderBy(f => f, FilterInfoComparer.Instance);
- _filterPipeline = new Collection<FilterInfo>(filters.ToList());
- }
- }
- }
+ // Need to discard duplicate filters from the end, so that most specific ones get kept (Action scope) and
+ // less specific ones get removed (Global)
+ filters = RemoveDuplicates(filters.Reverse()).Reverse();
- return _filterPipeline;
+ return new Collection<FilterInfo>(filters.ToList());
}
private static IEnumerable<FilterInfo> RemoveDuplicates(IEnumerable<FilterInfo> filters)
diff --git a/src/System.Web.Http/Dispatcher/DefaultHttpControllerFactory.cs b/src/System.Web.Http/Dispatcher/DefaultHttpControllerFactory.cs
index 844396d0..37ef9d4d 100644
--- a/src/System.Web.Http/Dispatcher/DefaultHttpControllerFactory.cs
+++ b/src/System.Web.Http/Dispatcher/DefaultHttpControllerFactory.cs
@@ -22,9 +22,7 @@ namespace System.Web.Http.Dispatcher
private readonly HttpConfiguration _configuration;
private readonly HttpControllerTypeCache _controllerTypeCache;
- private readonly ConcurrentDictionary<string, HttpControllerDescriptor> _controllerInfoCache = new ConcurrentDictionary<string, HttpControllerDescriptor>();
- private bool _isControllerInfoCacheInitialized;
- private object _controllerInfoCacheLock = new object();
+ private readonly Lazy<ConcurrentDictionary<string, HttpControllerDescriptor>> _controllerInfoCache;
/// <summary>
/// Initializes a new instance of the <see cref="DefaultHttpControllerFactory"/> class.
@@ -37,6 +35,7 @@ namespace System.Web.Http.Dispatcher
throw Error.ArgumentNull("resolver");
}
+ _controllerInfoCache = new Lazy<ConcurrentDictionary<string, HttpControllerDescriptor>>(InitializeControllerInfoCache);
_configuration = configuration;
_controllerTypeCache = new HttpControllerTypeCache(_configuration);
}
@@ -55,7 +54,7 @@ namespace System.Web.Http.Dispatcher
}
HttpControllerDescriptor controllerDescriptor;
- if (_controllerInfoCache.TryGetValue(controllerName, out controllerDescriptor))
+ if (_controllerInfoCache.Value.TryGetValue(controllerName, out controllerDescriptor))
{
// Create controller instance
return CreateInstance(controllerContext, controllerDescriptor);
@@ -76,7 +75,7 @@ namespace System.Web.Http.Dispatcher
// Add controller descriptor to cache
controllerDescriptor = new HttpControllerDescriptor(_configuration, controllerName, match);
- _controllerInfoCache.TryAdd(controllerName, controllerDescriptor);
+ _controllerInfoCache.Value.TryAdd(controllerName, controllerDescriptor);
// Create controller instance
return CreateInstance(controllerContext, controllerDescriptor);
@@ -100,8 +99,7 @@ namespace System.Web.Http.Dispatcher
public virtual IDictionary<string, HttpControllerDescriptor> GetControllerMapping()
{
- EnsureControllerInfoCacheInitialized();
- return _controllerInfoCache.ToDictionary(c => c.Key, c => c.Value, StringComparer.OrdinalIgnoreCase);
+ return _controllerInfoCache.Value.ToDictionary(c => c.Key, c => c.Value, StringComparer.OrdinalIgnoreCase);
}
private static IHttpController CreateInstance(HttpControllerContext controllerContext, HttpControllerDescriptor controllerDescriptor)
@@ -138,32 +136,39 @@ namespace System.Web.Http.Dispatcher
return Error.Format(SRResources.DefaultControllerFactory_ControllerNameAmbiguous_WithRouteTemplate, controllerName, route.RouteTemplate, typeList);
}
- private void EnsureControllerInfoCacheInitialized()
+ private ConcurrentDictionary<string, HttpControllerDescriptor> InitializeControllerInfoCache()
{
- if (!_isControllerInfoCacheInitialized)
+ var result = new ConcurrentDictionary<string, HttpControllerDescriptor>();
+ var duplicateControllers = new HashSet<string>();
+ Dictionary<string, ILookup<string, Type>> controllerTypeGroups = _controllerTypeCache.Cache;
+
+ foreach (KeyValuePair<string, ILookup<string, Type>> controllerTypeGroup in controllerTypeGroups)
{
- lock (_controllerInfoCacheLock)
+ string controllerName = controllerTypeGroup.Key;
+ foreach (IGrouping<string, Type> controllerTypesGroupedByNs in controllerTypeGroup.Value)
{
- if (!_isControllerInfoCacheInitialized)
+ foreach (Type controllerType in controllerTypesGroupedByNs)
{
- Dictionary<string, ILookup<string, Type>> controllerTypeGroups = _controllerTypeCache.Cache;
- foreach (KeyValuePair<string, ILookup<string, Type>> controllerTypeGroup in controllerTypeGroups)
+ if (result.Keys.Contains(controllerName))
{
- string controllerName = controllerTypeGroup.Key;
- foreach (var controllerTypesGroupedByNs in controllerTypeGroup.Value)
- {
- foreach (var controllerType in controllerTypesGroupedByNs)
- {
- var controllerDescriptor = new HttpControllerDescriptor(_configuration, controllerName, controllerType);
- _controllerInfoCache.TryAdd(controllerName, controllerDescriptor);
- }
- }
+ duplicateControllers.Add(controllerName);
+ break;
+ }
+ else
+ {
+ result.TryAdd(controllerName, new HttpControllerDescriptor(_configuration, controllerName, controllerType));
}
-
- _isControllerInfoCacheInitialized = true;
}
}
}
+
+ foreach (string duplicateController in duplicateControllers)
+ {
+ HttpControllerDescriptor descriptor;
+ result.TryRemove(duplicateController, out descriptor);
+ }
+
+ return result;
}
}
}
diff --git a/src/System.Web.Http/HttpServer.cs b/src/System.Web.Http/HttpServer.cs
index d614c75b..d7399042 100644
--- a/src/System.Web.Http/HttpServer.cs
+++ b/src/System.Web.Http/HttpServer.cs
@@ -25,8 +25,9 @@ namespace System.Web.Http
private readonly HttpConfiguration _configuration;
private readonly HttpMessageHandler _dispatcher;
private bool _disposed;
- private bool _initialized;
+ private bool _initialized = false;
private object _initializationLock = new object();
+ private object _initializationTarget;
/// <summary>
/// Initializes a new instance of the <see cref="HttpServer"/> class with default configuration and dispatcher.
@@ -160,26 +161,20 @@ namespace System.Web.Http
private void EnsureInitialized()
{
- if (!_initialized && !_disposed)
+ LazyInitializer.EnsureInitialized(ref _initializationTarget, ref _initialized, ref _initializationLock, () =>
{
- lock (_initializationLock)
- {
- if (!_initialized)
- {
- Initialize();
+ Initialize();
- // Attach tracing before creating pipeline to allow injection of message handlers
- ITraceManager traceManager = _configuration.ServiceResolver.GetTraceManager();
- Contract.Assert(traceManager != null);
- traceManager.Initialize(_configuration);
+ // Attach tracing before creating pipeline to allow injection of message handlers
+ ITraceManager traceManager = _configuration.ServiceResolver.GetTraceManager();
+ Contract.Assert(traceManager != null);
+ traceManager.Initialize(_configuration);
- // Create pipeline
- InnerHandler = HttpPipelineFactory.Create(_configuration.MessageHandlers, _dispatcher);
+ // Create pipeline
+ InnerHandler = HttpPipelineFactory.Create(_configuration.MessageHandlers, _dispatcher);
- _initialized = true;
- }
- }
- }
+ return null;
+ });
}
/// <summary>
diff --git a/src/System.Web.Mvc/Async/TaskAsyncActionDescriptor.cs b/src/System.Web.Mvc/Async/TaskAsyncActionDescriptor.cs
index 22e8e8b1..8f957861 100644
--- a/src/System.Web.Mvc/Async/TaskAsyncActionDescriptor.cs
+++ b/src/System.Web.Mvc/Async/TaskAsyncActionDescriptor.cs
@@ -131,8 +131,7 @@ namespace System.Web.Mvc.Async
tokenSource.Cancel();
}
}
- },
- state: null, dueTime: timeout, period: Timeout.Infinite);
+ }, state: null, dueTime: timeout, period: Timeout.Infinite);
}
Task taskUser = dispatcher.Execute(controllerContext.Controller, parametersArray) as Task;
diff --git a/src/System.Web.Mvc/ControllerTypeCache.cs b/src/System.Web.Mvc/ControllerTypeCache.cs
index 7b560f4a..a4a8ca7a 100644
--- a/src/System.Web.Mvc/ControllerTypeCache.cs
+++ b/src/System.Web.Mvc/ControllerTypeCache.cs
@@ -7,7 +7,7 @@ namespace System.Web.Mvc
{
private const string TypeCacheName = "MVC-ControllerTypeCache.xml";
- private Dictionary<string, ILookup<string, Type>> _cache;
+ private volatile Dictionary<string, ILookup<string, Type>> _cache;
private object _lockObj = new object();
internal int Count
diff --git a/src/System.Web.Mvc/MultiServiceResolver.cs b/src/System.Web.Mvc/MultiServiceResolver.cs
index d3506fa2..0eedd385 100644
--- a/src/System.Web.Mvc/MultiServiceResolver.cs
+++ b/src/System.Web.Mvc/MultiServiceResolver.cs
@@ -6,7 +6,7 @@ namespace System.Web.Mvc
internal class MultiServiceResolver<TService> : IResolver<IEnumerable<TService>>
where TService : class
{
- private IEnumerable<TService> _itemsFromService;
+ private Lazy<IEnumerable<TService>> _itemsFromService;
private Func<IEnumerable<TService>> _itemsThunk;
private Func<IDependencyResolver> _resolverThunk;
@@ -19,6 +19,7 @@ namespace System.Web.Mvc
_itemsThunk = itemsThunk;
_resolverThunk = () => DependencyResolver.Current;
+ _itemsFromService = new Lazy<IEnumerable<TService>>(() => _resolverThunk().GetServices<TService>());
}
internal MultiServiceResolver(Func<IEnumerable<TService>> itemsThunk, IDependencyResolver resolver)
@@ -32,20 +33,7 @@ namespace System.Web.Mvc
public IEnumerable<TService> Current
{
- get
- {
- if (_itemsFromService == null)
- {
- lock (_itemsThunk)
- {
- if (_itemsFromService == null)
- {
- _itemsFromService = _resolverThunk().GetServices<TService>();
- }
- }
- }
- return _itemsFromService.Concat(_itemsThunk());
- }
+ get { return _itemsFromService.Value.Concat(_itemsThunk()); }
}
}
}
diff --git a/src/System.Web.Mvc/SingleServiceResolver.cs b/src/System.Web.Mvc/SingleServiceResolver.cs
index b1f5c344..ae2400c0 100644
--- a/src/System.Web.Mvc/SingleServiceResolver.cs
+++ b/src/System.Web.Mvc/SingleServiceResolver.cs
@@ -6,7 +6,7 @@ namespace System.Web.Mvc
internal class SingleServiceResolver<TService> : IResolver<TService>
where TService : class
{
- private TService _currentValueFromResolver;
+ private Lazy<TService> _currentValueFromResolver;
private Func<TService> _currentValueThunk;
private TService _defaultValue;
private Func<IDependencyResolver> _resolverThunk;
@@ -24,6 +24,7 @@ namespace System.Web.Mvc
}
_resolverThunk = () => DependencyResolver.Current;
+ _currentValueFromResolver = new Lazy<TService>(GetValueFromResolver);
_currentValueThunk = currentValueThunk;
_defaultValue = defaultValue;
_callerMethodName = callerMethodName;
@@ -40,26 +41,19 @@ namespace System.Web.Mvc
public TService Current
{
- get
- {
- if (_resolverThunk != null)
- {
- lock (_currentValueThunk)
- {
- if (_resolverThunk != null)
- {
- _currentValueFromResolver = _resolverThunk().GetService<TService>();
- _resolverThunk = null;
+ get { return _currentValueFromResolver.Value ?? _currentValueThunk() ?? _defaultValue; }
+ }
+
+ private TService GetValueFromResolver()
+ {
+ TService result = _resolverThunk().GetService<TService>();
- if (_currentValueFromResolver != null && _currentValueThunk() != null)
- {
- throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.SingleServiceResolver_CannotRegisterTwoInstances, typeof(TService).Name.ToString(), _callerMethodName));
- }
- }
- }
- }
- return _currentValueFromResolver ?? _currentValueThunk() ?? _defaultValue;
+ if (result != null && _currentValueThunk() != null)
+ {
+ throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.SingleServiceResolver_CannotRegisterTwoInstances, typeof(TService).Name.ToString(), _callerMethodName));
}
+
+ return result;
}
}
}
diff --git a/src/System.Web.Mvc/UrlRewriterHelper.cs b/src/System.Web.Mvc/UrlRewriterHelper.cs
index 265f7202..5a08542b 100644
--- a/src/System.Web.Mvc/UrlRewriterHelper.cs
+++ b/src/System.Web.Mvc/UrlRewriterHelper.cs
@@ -9,7 +9,7 @@ namespace System.Web.Mvc
private object _lockObject = new object();
private bool _urlRewriterIsTurnedOnValue;
- private bool _urlRewriterIsTurnedOnCalculated = false;
+ private volatile bool _urlRewriterIsTurnedOnCalculated = false;
private static bool WasThisRequestRewritten(HttpContextBase httpContext)
{