Asp.net MVC源码分析--DependencyResolver与Service Location
这一篇我们讲解如何利用DependencyResolver来定位我们的自定义服务(service)也就查找Controller.
首先让我们来看一下DependencyResolver 的实现。
DependencyResolver.cs
1 public class DependencyResolver {
2 // Static accessors
3
4 private static DependencyResolver _instance = new DependencyResolver();
5
6 public static IDependencyResolver Current {
7 get {
8 return _instance.InnerCurrent;
9 }
10 }
11
12 public static void SetResolver(IDependencyResolver resolver) {
13 _instance.InnerSetResolver(resolver);
14 }
15
16 public static void SetResolver(object commonServiceLocator) {
17 _instance.InnerSetResolver(commonServiceLocator);
18 }
19
20 [SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "This is an appropriate nesting of generic types.")]
21 public static void SetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices) {
22 _instance.InnerSetResolver(getService, getServices);
23 }
24
25 // Instance implementation (for testing purposes)
26
27 private IDependencyResolver _current = new DefaultDependencyResolver();
28
29 public IDependencyResolver InnerCurrent {
30 get {
31 return _current;
32 }
33 }
34
35 private class DefaultDependencyResolver : IDependencyResolver {
36 [SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes", Justification = "This method might throw exceptions whose type we cannot strongly link against; namely, ActivationException from common service locator")]
37 public object GetService(Type serviceType) {
38 try {
39 return Activator.CreateInstance(serviceType);
40 }
41 catch {
42 return null;
43 }
44 }
45
46 public IEnumerable<object> GetServices(Type serviceType) {
47 return Enumerable.Empty<object>();
48 }
49 }
50 }
51
52
DependencyResolver.Current 默认返回的是DefaultDependencyResolver 类型的实例,在这个类中我们看到它实现了IDependencyResolver.GetService 接口, 这个实现是调用了Activator.CreateInstance(serviceType); 返回一个类型的实例。
这里框架为我们提供了一个时点使我们可以调用DependencyResolver.SetResolver方法来注入我们自己的IDependencyResolver的实现。
---------------------------------------------------------------------------------------------
接下来我们看MvcHandler,所有的Request请需要在这里查找我们的Controller,在这个类的ProcessRequestInit方法中我们可以看到它调用了ControllerBuilder.GetControllerFactory(); 先找到Controller的工成类实例IControllerFactory,再调用它的CreateController方法来寻找和创建Controller.
MvcHandler.cs
1 private void ProcessRequestInit(HttpContextBase httpContext, out IController controller, out IControllerFactory factory) {
2 // If request validation has already been enabled, make it lazy. This allows attributes like [HttpPost] (which looks
3 // at Request.Form) to work correctly without triggering full validation.
4 bool? isRequestValidationEnabled = ValidationUtility.IsValidationEnabled(HttpContext.Current);
5 if (isRequestValidationEnabled == true) {
6 ValidationUtility.EnableDynamicValidation(HttpContext.Current);
7 }
8
9 AddVersionHeader(httpContext);
10 RemoveOptionalRoutingParameters();
11
12 // Get the controller type
13 string controllerName = RequestContext.RouteData.GetRequiredString("controller");
14
15 // Instantiate the controller and call Execute
16 factory = ControllerBuilder.GetControllerFactory();
17 controller = factory.CreateController(RequestContext, controllerName);
18 if (controller == null) {
19 &nb
补充:Web开发 , ASP.Net ,