zoukankan      html  css  js  c++  java
  • Ihttpmodule 的一个小问题,今天明白了

             最近有时间看一些.net的框架代码,发现一个有意思的问题,就是HttpModule中的Init函数下的事件绑定,因为事件
    的绑定在事件发生后相应的处理委托即为null,但下面的代码(功能:地址的重定向)为什么只是绑定一次后就能在每个
    WEB请求过来时都能运行
    ReUrl_BeginRequest事件呢。

    public class HttpModule : System.Web.IHttpModule
    {
         public void Init(HttpApplication context)
         {
      context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
            ....
         }

         private void ReUrl_BeginRequest(object sender, EventArgs e)
         {
             ....
         }


             原因主要是出现System.Web.HttpApplication 中的这个函数HookupEventHandlersForAppplicationAndModules这个函
    数(如下)


    private void HookupEventHandlersForAppplicationAndModules(MethodInfo[] handlers)
    {
          
    for (int num1 = 0; num1 < handlers.Length; num1++)
          
    {
                MethodInfo info1 
    = handlers[num1];
                
    string text1 = info1.Name;
                
    int num2 = text1.IndexOf('_');
                
    string text2 = text1.Substring(0, num2);
                
    object obj1 = null;
                
    if (string.Compare(text2, "Application"true, CultureInfo.InvariantCulture) == 0)
                
    {
                      obj1 
    = this;
                }

                
    else if (this._moduleCollection != null)
                
    {
                      obj1 
    = this._moduleCollection[text2];
                }

                
    if (obj1 != null)
                
    {
                      Type type1 
    = obj1.GetType();
                      EventDescriptorCollection collection1 
    = TypeDescriptor.GetEvents(type1);
                      
    string text3 = text1.Substring(num2 + 1);
                      EventDescriptor descriptor1 
    = collection1.Find(text3, true);
                      
    if ((descriptor1 == null&& (string.Compare(text3.Substring(02), "on"true, CultureInfo.InvariantCulture) == 0))
                      
    {
                            text3 
    = text3.Substring(2);
                            descriptor1 
    = collection1.Find(text3, true);
                      }

                      MethodInfo info2 
    = null;
                      
    if (descriptor1 != null)
                      
    {
                            EventInfo info3 
    = type1.GetEvent(descriptor1.Name);
                            
    if (info3 != null)
                            
    {
                                  info2 
    = info3.GetAddMethod();
                            }

                      }

                      
    if (info2 != null)
                      
    {
                            ParameterInfo[] infoArray1 
    = info2.GetParameters();
                            
    if (infoArray1.Length == 1)
                            
    {
                                  Delegate delegate1 
    = null;
                                  ParameterInfo[] infoArray2 
    = info1.GetParameters();
                                  
    if (infoArray2.Length == 0)
                                  
    {
                                        
    if (infoArray1[0].ParameterType != typeof(EventHandler))
                                        
    {
                                              
    goto Label_0168;
                                        }

                                        ArglessEventHandlerProxy proxy1 
    = new ArglessEventHandlerProxy(this, info1);
                                        delegate1 
    = proxy1.Handler;
                                  }

                                  
    else
                                  
    {
                                        
    try
                                        
    {
                                              delegate1 
    = Delegate.CreateDelegate(infoArray1[0].ParameterType, this, text1);
                                        }

                                        
    catch (Exception)
                                        
    {
                                              
    goto Label_0168;
                                        }

                                  }

                                  
    try
                                  
    {
                                        info2.Invoke(obj1, 
    new object[] { delegate1 });
                                  }

                                  
    catch (Exception)
                                  
    {
                                  }

                            Label_0168:;
                            }

                      }

                }

          }

    }




             请注意_moduleCollection这个属性,它其实可以理解为一系列的HttpModule的集合,里面的数据主要是我们在web.config
    中的内容,如下:
             <httpModules>
             <add type="Discuz.Forum.HttpModule, Discuz.Forum" name="HttpModule" />
              </httpModules>
              上面的代码基本上是找出相关的HTTPMODULE或HANDLER中的绑定事件,然后去运行。
     
              那是什么函数实现了将web.config中的设置获取到_moduleCollection变量中呢,InitModules()这个函数不名思议就是干
    这个活的,它的代码如下

    private void InitModules()
    {
          HttpModulesConfiguration configuration1 
    = (HttpModulesConfiguration) HttpContext.GetAppConfig("system.web/httpModules");
          
    if (configuration1 == null)
          
    {
                
    throw new HttpException(HttpRuntime.FormatResourceString("Missing_modules_config"));
          }

          
    this._moduleCollection = configuration1.CreateModules();
          
    int num1 = this._moduleCollection.Count;
          
    for (int num2 = 0; num2 < num1; num2++)
          
    {
                
    this._moduleCollection[num2].Init(this);
          }

          GlobalizationConfig config1 
    = (GlobalizationConfig) HttpContext.GetAppConfig("system.web/globalization");
          
    if (config1 != null)
          
    {
                
    this._appLevelCulture = config1.Culture;
                
    this._appLevelUICulture = config1.UICulture;
          }

    }

               另外它还运行了Init方法,而这个方法所干的活就是我们在实现IHTTPMODULE中所希望的操作即:
               {
                 context.BeginRequest += new EventHandler(ReUrl_BeginRequest);
                  .....
              }

             这样当外部请求来时,系统会运行到System.Web.HttpApplication.InitInternal函数,它会去调用
    HookupEventHandlersForAppplicationAndModules,
    这样就能在只绑定一次事件之后,即使有新的请求到来是时,系统依然知道要去运行那些要处理的事件。

             这篇文章没有什么技术含量,因为很长时间没写东西了,所以发了出来, 希望大家见谅,献丑了。
     
       
        参考文章:http://www.cnblogs.com/dudu/archive/2006/01/14/317016.html

  • 相关阅读:
    关于android中两种service的编写简单总结
    To learn list
    android中如何在系统启动的时候启动自己的service
    service的生命周期以及两种service的差异
    Intent的简单概述
    关于startactivity初始化activity的过程以及activity和window以及view的关系
    android activity生命周期的一张经典图片
    关于Android进程的启动和消亡
    Java基础学习总结(73)——Java最新面试题汇总
    Beetl学习总结(4)——Web集成
  • 原文地址:https://www.cnblogs.com/daizhj/p/669479.html
Copyright © 2011-2022 走看看