亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

Asp.net MVC源碼分析--DependencyResolver與Ser

系統 2546 0

這一篇我們講解如何利用DependencyResolver來定位我們的自定義服務(service)也就查找Controller.

首先讓我們來看一下DependencyResolver 的實現。

DependencyResolver.cs

View Code
        
           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

View Code
        
           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 throw new InvalidOperationException(
20 String.Format(
21 CultureInfo.CurrentCulture,
22 MvcResources.ControllerBuilder_FactoryReturnedNull,
23 factory.GetType(),
24 controllerName));
25 }
26 }

-------------------------------------------------------------------------------------------

下面我們看一下ControllerBuilder類,看一下它是如何工作的。

ControllerBuilder.cs

View Code
        
           1
        
        
          public
        
        
          class
        
         ControllerBuilder {
        
2
3 private Func<IControllerFactory> _factoryThunk = () => null ;
4 private static ControllerBuilder _instance = new ControllerBuilder();
5 private HashSet< string > _namespaces = new HashSet< string >(StringComparer.OrdinalIgnoreCase);
6 private IResolver<IControllerFactory> _serviceResolver;
7
8 public ControllerBuilder()
9 : this ( null ) {
10 }
11
12 internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver) {
13 _serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
14 () => _factoryThunk(),
15 new DefaultControllerFactory { ControllerBuilder = this },
16 " ControllerBuilder.GetControllerFactory "
17 );
18 }
19
20 public IControllerFactory GetControllerFactory() {
21 return _serviceResolver.Current;
22 }
23 }

在構造函數中我們看到它初始化了_serviceResolver 變量,它的類型是SingleServiceResolver<IControllerFactory>,在它初始化時傳入了_factoryThunk(返回值為空的委托),和DefaultControllerFactory實例。接下來我們看一下SingleServiceResolver的實現。

SingleServiceResolver.cs

View Code
        
           1
        
        
          internal
        
        
          class
        
         SingleServiceResolver<TService> : IResolver<TService> 
        
          where
        
         TService : 
        
          class
        
         {
        
2
3 private TService _currentValueFromResolver;
4 private Func<TService> _currentValueThunk;
5 private TService _defaultValue;
6 private Func<IDependencyResolver> _resolverThunk;
7 private string _callerMethodName;
8
9 public SingleServiceResolver(Func<TService> currentValueThunk, TService defaultValue, string callerMethodName) {
10 if (currentValueThunk == null ) {
11 throw new ArgumentNullException( " currentValueThunk " );
12 }
13 if (defaultValue == null ) {
14 throw new ArgumentNullException( " defaultValue " );
15 }
16
17 _resolverThunk = () => DependencyResolver.Current;
18 _currentValueThunk = currentValueThunk;
19 _defaultValue = defaultValue;
20 _callerMethodName = callerMethodName;
21 }
22
23 internal SingleServiceResolver(Func<TService> staticAccessor, TService defaultValue, IDependencyResolver resolver, string callerMethodName)
24 : this (staticAccessor, defaultValue, callerMethodName) {
25 if (resolver != null ) {
26 _resolverThunk = () => resolver;
27 }
28 }
29
30 public TService Current {
31 get {
32 if (_resolverThunk != null ) {
33 lock (_currentValueThunk) {
34 if (_resolverThunk != null ) {
35 _currentValueFromResolver = _resolverThunk().GetService<TService>();
36 _resolverThunk = null ;
37
38 if (_currentValueFromResolver != null && _currentValueThunk() != null ) {
39 throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, MvcResources.SingleServiceResolver_CannotRegisterTwoInstances, typeof (TService).Name.ToString(), _callerMethodName));
40 }
41 }
42 }
43 }
44 return _currentValueFromResolver ?? _currentValueThunk() ?? _defaultValue;
45 }
46 }
47 }

我們看到?

_resolverThunk = () => DependencyResolver.Current;//這里就為我們注入自己的ControllerFactory提供機會_currentValueFromResolver = _resolverThunk().GetService<TService>();我們知道框架使用了DependencyResolver.Current來提供GetService的功能,如果沒有則返回默認的DefaultControllerFactory實例(從構造函數中傳入)。

--------------------------------------------------------------------------------------------

接下來我們看DefaultControllerFactory的實現,

View Code
        
           1
        
        
          public
        
        
          class
        
         DefaultControllerFactory : IControllerFactory {
        
2 public DefaultControllerFactory()
3 : this ( null , null , null ) {
4 }
5
6 public DefaultControllerFactory(IControllerActivator controllerActivator)
7 : this (controllerActivator, null , null ) {
8 }
9
10 internal DefaultControllerFactory(IControllerActivator controllerActivator, IResolver<IControllerActivator> activatorResolver, IDependencyResolver dependencyResolver) {
11 if (controllerActivator != null ) {
12 _controllerActivator = controllerActivator;
13 }
14 else {
15 _activatorResolver = activatorResolver ?? new SingleServiceResolver<IControllerActivator>(
16 () => null ,
17 new DefaultControllerActivator(dependencyResolver),
18 " DefaultControllerFactory contstructor "
19 );
20 }
21 }
22
23 private IControllerActivator ControllerActivator {
24 get {
25 if (_controllerActivator != null ) {
26 return _controllerActivator;
27 }
28 _controllerActivator = _activatorResolver.Current;
29 return _controllerActivator;
30 }
31 }
32
33 public virtual IController CreateController(RequestContext requestContext, string controllerName) {
34 if (requestContext == null ) {
35 throw new ArgumentNullException( " requestContext " );
36 }
37 if (String.IsNullOrEmpty(controllerName)) {
38 throw new ArgumentException(MvcResources.Common_NullOrEmpty, " controllerName " );
39 }
40 Type controllerType = GetControllerType(requestContext, controllerName);
41 IController controller = GetControllerInstance(requestContext, controllerType);
42 return controller;
43 }
44
45 protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
46
47 return ControllerActivator.Create(requestContext, controllerType);
48 }
49
50
51
52 private class DefaultControllerActivator : IControllerActivator {
53 Func<IDependencyResolver> _resolverThunk;
54
55 public DefaultControllerActivator()
56 : this ( null ) {
57 }
58
59 public DefaultControllerActivator(IDependencyResolver resolver) {
60 if (resolver == null ) {
61 _resolverThunk = () => DependencyResolver.Current;
62 }
63 else {
64 _resolverThunk = () => resolver;
65 }
66 }
67
68 public IController Create(RequestContext requestContext, Type controllerType) {
69 try {
70 return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType));
71 }
72 catch (Exception ex) {
73 throw new InvalidOperationException(
74 String.Format(
75 CultureInfo.CurrentCulture,
76 MvcResources.DefaultControllerFactory_ErrorCreatingController,
77 controllerType),
78 ex);
79 }
80 }
81 }
82 }
83 }

在這個類中我們同樣看到了和ControllerBuilder中一樣的模式,也是利用SingleServiceResolver,來初始化IControllerActivator實例。如果在DependencyResolver.Current中沒有找到IControllerActivator類型的話使用DefaultControllerActivator.最終利用DefaultControllerActivator.Create方法創建Controller的實例。

這里框架又提供了一個時點讓我們注冊自已實現的IControllerActivator類。 ?

總結:

DependencyResolver 與?SingleServiceResolver/MutiServiceResolver 在MVC框架中配合使用的。

只要用到了ServiceResolver的地方,我們都可能通過在DependencyResolver 注冊自己的行為從而改變框架的行為。

?

口渴中。。?

不知道說清楚沒,下一篇我們分析Ninject.MVC 與 asp.net MVC 的集成。

?

轉載請注明出處: http://www.cnblogs.com/RobbinHan/archive/2011/12/05/2270707.html ?

本文作者:?十一月的雨? http://www.cnblogs.com/RobbinHan

?

Asp.net MVC源碼分析--DependencyResolver與Service Location


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦?。?!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 激情在线视频 | 欧美黄色录像 | 久操网址 | 日本aⅴ在线 | 97视频在线免费观看 | 一级寡妇乱色毛片全18 | 亚洲mv在线观看 | 久久精品一区二区三区中文字幕 | 久久久男女野外野战 | 亚洲欧美色综合自拍 | 狠狠色丁香久久婷婷综合丁香 | 四虎永久免费观看 | 5g影院天天5g天天爽精品 | 欧美久久视频 | 蜜桃久久久久久久久久久 | 五月婷婷伊人网 | 午夜一区二区在线观看 | 日本毛片大全 | 亚洲网站视频 | 欧美性猛交xxxx免费看久久久 | 99精品国产兔费观看久久99 | 久久综合九色综合97婷婷群聊 | 人人狠狠综合久久亚洲 | 99精品视频在线 | 日本中文字幕一区二区高清在线 | 久久国产成人精品麻豆 | 欧美国产一区二区二区 | 伊人久久大香线蕉综合bd高清 | 国产一区二 | 999久久久免费精品国产牛牛 | 亚洲欧美日韩国产综合专区 | 国内久久久久影院精品 | 久久亚洲综合中文字幕 | 美女胸又大又黄www网站 | 国产成人在线免费观看 | 国产成人精品久久综合 | 奇米第四色网站 | 亚洲 国产 图片 | 成人午夜精品久久久久久久小说 | 国产亚洲精品自在线观看 | 国产欧美日韩在线观看 |