Merge pull request #301 from directhex/master
[mono.git] / mcs / class / System.Web.Mvc3 / Mvc / SingleServiceResolver.cs
1 namespace System.Web.Mvc {
2     using System.Globalization;
3     using System.Web.Mvc.Resources;
4
5     internal class SingleServiceResolver<TService> : IResolver<TService> where TService : class {
6
7         private TService _currentValueFromResolver;
8         private Func<TService> _currentValueThunk;
9         private TService _defaultValue;
10         private Func<IDependencyResolver> _resolverThunk;
11         private string _callerMethodName;
12
13         public SingleServiceResolver(Func<TService> currentValueThunk, TService defaultValue, string callerMethodName) {
14             if (currentValueThunk == null) {
15                 throw new ArgumentNullException("currentValueThunk");
16             }
17             if (defaultValue == null) {
18                 throw new ArgumentNullException("defaultValue");
19             }
20
21             _resolverThunk = () => DependencyResolver.Current;
22             _currentValueThunk = currentValueThunk;
23             _defaultValue = defaultValue;
24             _callerMethodName = callerMethodName;
25         }
26
27         internal SingleServiceResolver(Func<TService> staticAccessor, TService defaultValue, IDependencyResolver resolver, string callerMethodName)
28             : this(staticAccessor, defaultValue, callerMethodName) {
29             if (resolver != null) {
30                 _resolverThunk = () => resolver;
31             }
32         }
33
34         public TService Current {
35             get {
36                 if (_resolverThunk != null) {
37                     lock (_currentValueThunk) {
38                         if (_resolverThunk != null) {
39                             _currentValueFromResolver = _resolverThunk().GetService<TService>();
40                             _resolverThunk = null;
41
42                             if (_currentValueFromResolver != null && _currentValueThunk() != null) {
43                                 throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.SingleServiceResolver_CannotRegisterTwoInstances, typeof(TService).Name.ToString(), _callerMethodName));
44                             }
45                         }
46                     }
47                 }
48                 return _currentValueFromResolver ?? _currentValueThunk() ?? _defaultValue;
49             }
50         }
51     }
52 }