不使用配置文件动态注册HttpModule

在asp.net 4.0中,提供了一种不通过修改配置文件注册Module的方法。从.net3.5开始,新提供的PreApplicationStartMethodAttribute特性可以应用在程序集上,使得自定义的网站初始化代码可以在web应用程序的Application_Start初始化环节之前就执行。这个步骤甚至在动态编译和执行Application_Start之前。对于每个程序集,可以定义一次,PreApplicationStartMethodAttribute定义如下:

#region Assembly System.Web.dll, v4.0.0.0
// C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.5\System.Web.dll
#endregion

using System;

namespace System.Web
{
    // Summary:
    //     Provides expanded support for application startup.
    [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = true)]
    public sealed class PreApplicationStartMethodAttribute : Attribute
    {
        // Summary:
        //     Initializes a new instance of the System.Web.PreApplicationStartMethodAttribute
        //     class.
        //
        // Parameters:
        //   type:
        //     An object that describes the type of the startup method..
        //
        //   methodName:
        //     An empty parameter signature that has no return value.
        public PreApplicationStartMethodAttribute(Type type, string methodName);

        // Summary:
        //     Gets the associated startup method.
        //
        // Returns:
        //     A string that contains the name of the associated startup method.
        public string MethodName { get; }
        //
        // Summary:
        //     Gets the type that is returned by the associated startup method.
        //
        // Returns:
        //     An object that describes the type of the startup method.
        public Type Type { get; }
    }
}

Type用来指定定义了初始化方法的类型,MethodName用来指定将要执行的初始化方法。

通过这种方式,我们可以不在配置文件中固定配置HttpModule,而是定义一个方法,这个方法可以返回需要动态注册的HttpModule,将这个方法以委托的方式等级在一个集合中。在网站启动之前后,每当HttpApplicationFactory创建一个HttpApplication对象,完成正常注册的HttpModule创建及初始化之后,再来创建我们动态注册的这些HttpModule。

对于HttpApplication来说,其Init方法将在网站正常注册的HttpModule创建及注册之后被调用,用来完成自定义的HttpApplication初始化。我们可以在这个时间点动态注册HttpModule。在asp.net网站中,Global.asax文件用来生成一个HttpApplication的派生类。这个类用来创建网站中使用的HttpApplication对象,这就为我们提供了一个时间点,我们可以重写这个派生类的Init方法,完成动态注册HttpModule创建和注册工作。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Security;
using System.Web.SessionState;

namespace HttpRequestDemo
{
    public class Global : System.Web.HttpApplication
    {
        private List<IHttpModule> dynamicModules;
        public override void Init()
        {
            base.Init();
            this.dynamicModules = DynamicHttpModuleManager.GetModules();
            foreach (var item in this.dynamicModules)
            {
                item.Init(this);
            }
        }
        protected void Application_Start(object sender, EventArgs e)
        {
        }
    }

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace UserModule
{
    public delegate IHttpModule CreateDynamicHttpModule();
    public static class DynamicHttpModuleManager
    {
        private static List<CreateDynamicHttpModule> _createModuleHandlerList = new List<CreateDynamicHttpModule>();
        /// <summary>
        /// 在网站初始化之前,将需要注册的Module类型记录在一个集合中
        /// </summary>
        /// <param name="handler"></param>
        public static void RegisterDynamicModule(CreateDynamicHttpModule handler)
        {
            _createModuleHandlerList.Add(handler);
        }
        /// <summary>
        /// 获取要注册的HttpModule
        /// </summary>
        /// <returns></returns>
        public static List<IHttpModule> GetModules()
        {
            List<IHttpModule> lst = new List<IHttpModule>();
            foreach (var item in _createModuleHandlerList)
            {
                IHttpModule module = item();
                lst.Add(module);
            }
            return lst;
        }
    }

}

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web;

namespace UserModule
{
    //自定义的HttpModule中,添加一个Rgister方法,用来注册
    public class OnlineUserModule:IHttpModule
    {
        public static void Register()
        {
            DynamicHttpModuleManager.RegisterDynamicModule(() => new OnlineUserModule());
        }
        public void Dispose()
        {
            throw new NotImplementedException();
        }

        public void Init(HttpApplication context)
        {
            throw new NotImplementedException();
        }
    }
}

最后在项目的AssemblyInfo.cs文件中增加PreApplicationStartMethod特征完成动态注册。

[assembly: PreApplicationStartMethod(typeof(UserModule.OnlineUserModule), "Register")]

 注意这里的AssemblyInfo.cs是指的你的程序集的。在里面添加这个PreApplicationStartMethod。然后运行web项目,你会发现,断点会进入你的自定义的HttpModule。

博客地址: http://www.cnblogs.com/wolf-sun/
博客版权: 本文以学习、研究和分享为主,欢迎转载,但必须在文章页面明显位置给出原文连接。
如果文中有不妥或者错误的地方还望高手的你指出,以免误人子弟。如果觉得本文对你有所帮助不如【推荐】一下!如果你有更好的建议,不如留言一起讨论,共同进步!
再次感谢您耐心的读完本篇文章。http://www.cnblogs.com/wolf-sun/p/5244839.html
时间: 2024-09-08 09:36:21

不使用配置文件动态注册HttpModule的相关文章

MVC系列(6) 动态注册HttpModule

通过前面的章节,我们知道HttpApplication在初始化的时候会初始化所有配置文件里注册的HttpModules,那么有一个疑问,能否初始化之前动态加载HttpModule,而不是只从Web.config里读取? 答案是肯定的, ASP.NET MVC3发布的时候提供了一个Microsoft.Web.Infrastructure.dll文件,这个文件就是提供了动态注册HttpModule的功能,那么它是如何以注册的呢?我们先去MVC3的源码看看该DLL的源代码. 注:该DLL位置在C:\P

动态注册bean到spring容器

原先的设计是通过已有的库,将数据通过rmi写入到远程服务器:现在有需求需要将支持多个,而且是自定义的远程服务器ip. 因为整个接口原先都是通过spring配置文件,包括rmi的地址.同时,为了维护方便,不能直接将打好的jar包拿过来改,于是就采用了复制原有的bean definition,动态注册新的bean到那个spring容器中. 首先需要获取jar包中的spring容器,这里需要将applicationContext接口转换成为真正的实现:DefaultListableBeanFactor

java开发中动态注册bean到spring框架容器

原先的设计是通过已有的库,将数据通过rmi写入到远程服务器:现在有需求需要将支持多个,而且是自定义的远程服务器ip. 因为整个接口原先都是通过spring配置文件,包括rmi的地址.同时,为了维护方便,不能直接将打好的jar包拿过来改,于是就采用了复制原有的bean definition,动态注册新的bean到那个spring容器中. 首先需要获取jar包中的spring容器,这里需要将applicationContext接口转换成为真正的实现:DefaultListableBeanFactor

一次访问问题排查-涉及TNS-03505、ORA-12154、TNS-12560、动态注册、防火墙、tnsping跟踪等

建了一个库,想通过Oracle Net访问,需要配置监听器和tnsnames.ora,接下来碰到一系列的问题... 1. 添加监听器配置,listener.ora文件默认包括: LISTENER =   (DESCRIPTION_LIST =     (DESCRIPTION =       (ADDRESS = (PROTOCOL = TCP)(HOST = localhost)(PORT = 1521))     )   ) ADR_BASE_LISTENER = /opt/app/ora1

Oracle数据库动态注册和参数local_listener的使用方法

从Oracle8i版本开始,在oracle数据库当中,应用如果没有特殊需求的话,数据库监听不需要做出配置,oracle把这种方法称为动态注册.所谓动态注册,oracle通过PMON进程根据参数instance_name和service_names中的内容,把oracle数据库的信息注册到默认的1521端口的监听器上.不管服务器端有几个监听程序,oracle默认都是注册到1521端口的监听器,也就是说,对于其他端口的监听器来说,如果想要正常的识别远程客户端提供的信息,需要做出配置,也就是静态注册.

Oracle Listener的动态注册

在有Oracle Listener的动态注册之前,采用的是静态注册,所谓静态注册是指Oracle实例在启动时 ,读取listener.ora里的配置,然后注册到Listener,它主要有两个缺点: 1. Listener不知道Oracle实例的实时状态 2. listener.ora里的配置比较麻烦,常需要手动修改. 动态注册 所谓动态注册是指Oracle实例启动后,会通过pmon进程实时的把实例状态和参数 (instance_name,service_name)同步给Listener,其中参数

第十六章_动态注册和Servlet容器初始化

16.1.动态注册 为了使动态注册成为可能,ServletContext接口中还添加了以下方法,用来动态地创建Web对象: <T extends Filter>createFilter(Java.lang.Class<T> clazz) <T extends java.util.EventListener> createListener(java.lang.Class<T> clazz) <T extends Servlet> createSer

广播监听-动态注册监听网络变化没显示?

问题描述 动态注册监听网络变化没显示? API 19的是改变了网络状态没吐司.. 解决方案 iOS动态监听网络变化网络变化监听iOS监听网络状态的变化 解决方案二: 首先确保你在工程的清单文件里注册了这个BroadcastReceiver对象,你看看有吗,还有你看看是否要添加某些权限,具体的我忘了. 解决方案三: 确定一下所有配置没有问题吗?

android broadCastReceive动态注册后必须调用注销吗?

问题描述 android broadCastReceive动态注册后必须调用注销吗? android broadCastReceive动态注册后必须调用注销吗?静态注册就算关闭程序,还会接收广播吗,静态注册能注销吗? 解决方案 最近在学广播接受者.印象中动态注册了不一定要注销的(不会直接导致报错),但是会一直占用资源,所以不用了建议注销掉.刚刚上网查了查:动态注册和静态注册一个BroadcastReceiver的区别:动态注册较静态注册灵活.实验证明:当静态注册一个BroadcastReceiv