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

Advertisement

在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。

Similar Posts:

  • 在Asp.net 4.0 中动态注册HttpModule

    using System; using System.Web; using Microsoft.Web.Infrastructure; namespace MvcApplication1 { public class CustomModule : IHttpModule { public void Init(HttpApplication context) { context.BeginRequest += new EventHandler(context_BeginRequest); } vo

  • 静态/动态注册 BroadcastReceiver 广播接收器

    Android 系统中的广播实质上指的是发送 Intent,用于在应用程序之间传送消息,但与 Activity 中使用的 Intent 是不同的.Activity 中的 Intent 是在前台执行的,广播中的 Intent 是在后台执行的.BroadcastReceiver 是广播接收器,用于接收来自系统和应用程序中的广播. 广播可以来源于系统,成为系统广播,也可以在应用程序中发出广播.发送广播是使用 android.content.ContentWrapper 方法,Activity 和 Se

  • Servlet - Upload、Download、Async、动态注册

    Servlet 标签 : Java与Web Upload-上传 随着3.0版本的发布,文件上传终于成为Servlet规范的一项内置特性,不再依赖于像Commons FileUpload之类组件,因此在服务端进行文件上传编程变得不费吹灰之力. 客户端 要上传文件, 必须利用multipart/form-data设置HTML表单的enctype属性,且method必须为POST: <form action="simple_file_upload_servlet.do" method=

  • 远程连接与数据库状态的联系——本质是监听器动态注册造成差异

    问题描述:我连一台ubuntu上的Oracle,但服务器必须启动到mount阶段才能连上. 但按理说连接跟实例没关系.而且连另一台redhat的Oracle就只打开监听器就可以了. 后来我查了ubuntu那台机子的listener.ora,发现里面没有注册,原来一直都是用的动态注册而不是静态注册(这里详情看Dave的博文Oracle Listener 动态注册 与 静态注册). 远程连接,要解析远程要连接的实例,然后在自己的注册清单里找对应的实例. 但监听器在数据库nomount模式时去找监听器

  • ORACLE 监听动态注册与静态注册

    注册就是将数据库作为一个服务注册到监听程序中.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请链接到数据库.这个服务名可以与数据库名一样,也有可能不一样. 在数据库服务启动的过程中,数据库服务器向监听程序中注册相应的服务.无论何时启动数据库,默认的都有两条信息注册到监听器中,即数据库服务器对应的实例和服务.客户端和服务器之间的链接,只需要提供一个服务名就可以了. 区分动态注册和静态注册 (1)使用listener.ora文件判断 动态注册 SID_LIST_LIST

  • 其他信息: 具有固定名称“Npgsql”的 ADO.NET 提供程序未在计算机或应用程序配置文件中注册或无法加载。有关详细信息,请参阅内部异常

    其他信息: 具有固定名称"Npgsql"的 ADO.NET 提供程序未在计算机或应用程序配置文件中注册或无法加载.有关详细信息,请参阅内部异常 解决方法 在 App.config 的 configuration 中加入下面的内容 其中 红底部分是你调用的Npgsql的版本号 <system.data> <DbProviderFactories> <remove invariant="Npgsql"/> <add name=&

  • Oracle监听静态注册和动态注册

    静态注册和动态注册总结 一.什么是注册? 注册就是将数据库作为一个服务注册到监听程序.客户端不需要知道数据库名和实例名,只需要知道该数据库对外提供的服务名就可以申请连接到数据库.这个服务名可能与实例名一样,也有可能不一样.在数据库服务器启动过程中,数据库服务器会向监听程序注册相应的服务(无论何时启动一个数据库,默认地都有两条信息注册到监听器中:数据库服务器对应的实例和服务.)相当于是这样:在数据库服务器和客户端之间有一监听程序(Listener),在监听程序中,会记录相应数据库对应的服务名(一个

  • Android(java)学习笔记173:BroadcastReceiver之 静态注册 和 动态注册

    1. 广播接受者 >什么是广播.收音机. 电台:对外发送信号. 收音机:接收电台的信号. >在android系统里面,系统有很多重要的事件: 电池电量低,插入充电器,sd卡被移除,有电话打出去,有短信发送进来. 静态注册,使用广播机制步骤: (1)买收音机 public class SDStatusReceiver extends BroadcastReceiver (2)装电池 <receiver android:name="com.itheima.sdstatus.SDSt

  • 使用lsnrctl status命令区分动态注册,静态注册

    unknow:静态注册 ready或blocked:动态注册 a.如果先启动监听,后启动数据库 Service "PLSExtProc" has 1 instance(s). Instance "PLSExtProc", status UNKNOWN, has 1 handler(s) for this service... Service "orcl" has 2 instance(s). Instance "ORCL",

  • spring 动态注册数据源

    spring实现多数据源,主需要向spring工厂动态注册数据源即可.代码: package com.htxx.service.dao; import java.io.IOException; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSource; i

Tags: