File: DependencyResolver.cs

package info (click to toggle)
mono 6.8.0.105%2Bdfsg-3.3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 1,284,512 kB
  • sloc: cs: 11,172,132; xml: 2,850,069; ansic: 671,653; cpp: 122,091; perl: 59,366; javascript: 30,841; asm: 22,168; makefile: 20,093; sh: 15,020; python: 4,827; pascal: 925; sql: 859; sed: 16; php: 1
file content (134 lines) | stat: -rw-r--r-- 5,482 bytes parent folder | download | duplicates (9)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
namespace System.Web.Mvc {
    using System.Collections.Generic;
    using System.Diagnostics.CodeAnalysis;
    using System.Globalization;
    using System.Linq;
    using System.Reflection;
    using System.Web.Mvc.Resources;

    public class DependencyResolver {
        // Static accessors

        private static DependencyResolver _instance = new DependencyResolver();

        public static IDependencyResolver Current {
            get {
                return _instance.InnerCurrent;
            }
        }

        public static void SetResolver(IDependencyResolver resolver) {
            _instance.InnerSetResolver(resolver);
        }

        public static void SetResolver(object commonServiceLocator) {
            _instance.InnerSetResolver(commonServiceLocator);
        }

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types.")]
        public static void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
            _instance.InnerSetResolver(getService, getServices);
        }

        // Instance implementation (for testing purposes)

        private IDependencyResolver _current = new DefaultDependencyResolver();

        public IDependencyResolver InnerCurrent {
            get {
                return _current;
            }
        }

        public void InnerSetResolver(IDependencyResolver resolver) {
            if (resolver == null) {
                throw new ArgumentNullException("resolver");
            }

            _current = resolver;
        }

        public void InnerSetResolver(object commonServiceLocator) {
            if (commonServiceLocator == null) {
                throw new ArgumentNullException("commonServiceLocator");
            }

            Type locatorType = commonServiceLocator.GetType();
            MethodInfo getInstance = locatorType.GetMethod("GetInstance", new[] { typeof(Type) });
            MethodInfo getInstances = locatorType.GetMethod("GetAllInstances", new[] { typeof(Type) });

            if (getInstance == null ||
                getInstance.ReturnType != typeof(object) ||
                getInstances == null ||
                getInstances.ReturnType != typeof(IEnumerable<object>)) {
                throw new ArgumentException(
                    String.Format(
                        CultureInfo.CurrentCulture,
                        MvcResources.DependencyResolver_DoesNotImplementICommonServiceLocator,
                        locatorType.FullName
                    ),
                    "commonServiceLocator"
                );
            }

            var getService = (Func<Type, object>)Delegate.CreateDelegate(typeof(Func<Type, object>), commonServiceLocator, getInstance);
            var getServices = (Func<Type, IEnumerable<object>>)Delegate.CreateDelegate(typeof(Func<Type, IEnumerable<object>>), commonServiceLocator, getInstances);

            _current = new DelegateBasedDependencyResolver(getService, getServices);
        }

        [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types.")]
        public void InnerSetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
            if (getService == null) {
                throw new ArgumentNullException("getService");
            }
            if (getServices == null) {
                throw new ArgumentNullException("getServices");
            }

            _current = new DelegateBasedDependencyResolver(getService, getServices);
        }

        // Helper classes

        private class DelegateBasedDependencyResolver : IDependencyResolver {
            Func<Type, object> _getService;
            Func<Type, IEnumerable<object>> _getServices;

            public DelegateBasedDependencyResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
                _getService = getService;
                _getServices = getServices;
            }

            [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
            public object GetService(Type type) {
                try {
                    return _getService.Invoke(type);
                }
                catch {
                    return null;
                }
            }

            public IEnumerable<object> GetServices(Type type) {
                return _getServices(type);
            }
        }

        private class DefaultDependencyResolver : IDependencyResolver {
            [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
            public object GetService(Type serviceType) {
                try {
                    return Activator.CreateInstance(serviceType);
                }
                catch {
                    return null;
                }
            }

            public IEnumerable<object> GetServices(Type serviceType) {
                return Enumerable.Empty<object>();
            }
        }
    }
}