[转载]ASP.NET 利器:在Global.asax之外实现Application_Start/End,程式元件使用就要这么灵活! – kudy – 博客园.
在System.Web命名空间下, .NET 4.0版本新增了一个 PreApplicationStartMethodAttribute 类,利用它可以Appilcation_Start()前触发的初始化工作。这里主要讲Kudy.Net项目中的System.Kudy.Web.Activating。事实上System.Kudy.Web.Activating也是靠它来运作的,功能很相近但 PreApplicationStartMethodAttribute 有些限制,一是整个Web Application只能加载一次(AllowMultiple=false),如果多个元件都有自己的初始事件就没办法,二是它只提供 Appilcation_Start()前触发的选项,相较之下,System.Kudy.Web.Activating应用起来更方便,因充它允许多次 注册并且还有Appilcation_Start()后触发和Appilcation_End()前触发的选项。
System.Kudy.Web.Activating下提供了四个属性分别是ActivationAttribute、 PreApplicationStartAttribute、PostApplicationStartAttribute和 PreApplicationEndAttribute,利用它们可以灵活地随时在你的程序集中注册一个或多个Appilcation_Start()前/后触发和Appilcation_End()前触发的处理事件。下面来新建一个Web Application项目来测试它们。
下载例子源码:ActivatingWeb.rar ActivatingMvcWeb.rar
请使用vs2010打开项目,本文对你有帮助的话请点下推荐支持,或关注本博客,谢谢。
首先,引用System.Kudy程序集(注意:System.Kudy有.Net3.5和.Net4.0版本的,4.0版本才支持此功能)。新建ActivatingTest类,然后在里面再加上几个测试类,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; // 引用命名空间 using System.Kudy.Web.Activating; // 在程序集注册应用程序触发事件(建议写在:AssemblyInfo.cs) [assembly: Activation( typeof (ActivatingWeb.MyApplication))] [assembly: Activation( typeof (ActivatingWeb.MyApplication_2))] [assembly: PreApplicationStart( typeof (ActivatingWeb.MyStaticApplication), "PreStart" )] [assembly: PostApplicationStart( typeof (ActivatingWeb.MyStaticApplication), "PostStart" )] [assembly: PreApplicationEnd( typeof (ActivatingWeb.MyStaticApplication), "PreEnd" )] namespace ActivatingWeb { public class ActivatingTest { // 用于显示测试事件调用情况 public static string OutputInfo = "" ; } /// <summary> /// 方式1:以静态方法来触发事件 /// [assembly: PreApplicationStart(typeof(ActivatingWeb.MyStaticApplication), "PreStart")] /// [assembly: PostApplicationStart(typeof(ActivatingWeb.MyStaticApplication), "PostStart")] /// [assembly: PreApplicationEnd(typeof(ActivatingWeb.MyStaticApplication), "PreEnd")] /// </summary> public class MyStaticApplication { public static void PreStart() { ActivatingTest.OutputInfo += "PreStart() in MyStaticApplication<br />" ; } public static void PostStart() { ActivatingTest.OutputInfo += "PostStart() in MyStaticApplication<br />" ; // 可以在此初始化 ASP.NET MVC 工作或 依赖注入(Dependency Injection),方式2类同 } public static void PreEnd() { ActivatingTest.OutputInfo += "<br />PreEnd() in MyStaticApplication<br />" ; // 可以在此做资源清理工作,方式2类同 } } /// <summary> /// 方式2:以实现接口来触发事件 /// [assembly: Activation(typeof(ActivatingWeb.MyApplication))] /// </summary> public class MyApplication : ActivationBase { public override void PreApplicationStart() { ActivatingTest.OutputInfo += "PreApplicationStart() in MyApplication<br />" ; } public override void PostApplicationStart() { ActivatingTest.OutputInfo += "PostApplicationStart() in MyApplication<br />" ; } public override void PreApplicationEnd() { ActivatingTest.OutputInfo += "PreApplicationEnd() in MyApplication<br />" ; } } /// <summary> /// 方式2:以实现接口来触发事件 /// [assembly: Activation(typeof(ActivatingWeb.MyApplication_2))] /// </summary> public class MyApplication_2 : IPreApplicationStart { public void PreApplicationStart() { ActivatingTest.OutputInfo += "PreApplicationStart() in MyApplication_2<br />" ; } } } |
上面写了两种基本使用的方式,我们再新建Global.asax文件来辅助测试工作,因为Application_End的工作无法在页面中显示,所以写在文件ActivatingTest.txt里了:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Security; using System.Web.SessionState; using System.Kudy; namespace ActivatingWeb { public class Global : System.Web.HttpApplication { protected void Application_Start( object sender, EventArgs e) { ActivatingTest.OutputInfo += "Application_Start() in Global<br />" ; } protected void Application_End( object sender, EventArgs e) { ActivatingTest.OutputInfo += "Application_End() in Global<br />" ; // 这时程序程序已结束,不可能在网页中显示结果 // 写进根目录下ActivatingTest.txt文件里查看吧 string file = EnvironmentUtil.GetFullPath( "ActivatingTest.txt" ); string content = ActivatingTest.OutputInfo.Replace( "<br />" , "\r\n" ); System.IO.File.WriteAllText(file, content); } } } |
最后在Default.aspx页面输入测试的结果:
public partial class _Default : System.Web.UI.Page { protected void Page_Load( object sender, EventArgs e) { // 输出调用结果 Response.Write(ActivatingTest.OutputInfo); Response.End(); } } |
运行网站,会看到输出结果如下(多刷新几次都是一样的结果):
打开Web.config,然后点击保存,这里网站结束了,可以看到根目录下ActivatingTest.txt的测试结果为:
可能有人会说,有了Global.asax就足够了。是的,如果没有特别需要是足够了。但是,使用 System.Kudy.Web.Activating可以使你的代码结构更清晰,维护方便,而且可以在不修改原来的代码就可以随时添加 Application_Start/Application_End的触发处理工作,使得安装程式元件不需要修改 Application_Start()就可以使用,或多或少降低安装复杂度。还值得说的是,在.Net4.0中提供了一个叫 DynamicModuleUtility的类(位于Microsoft.Web.Infrastructure.dll程序集),里面只有一个方法 RegisterModule(Type moduleType),利用它可以动态的添加HttpModule,MVC3都是动态注册模块的,所以4.0版本的System.Kudy不需要在 Web.config里配置地址重写模块了。当然,你还可以利用System.Kudy.Web.Activating方便的注册HttpModule。
网上还有个老外写的webactivator程序集是实现这样的功能的,本人测试过发现某情况下出现bug,可能有多次触发的情况。
再弄个MVC下的使用例子,把Global.asax删除了,再添加一个MyMvcApplication类,然后启动网站,可以正常运行:
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using System.Web.Routing; // 引用命名空间 using System.Kudy.Web.Activating; // 在程序集注册应用程序触发事件(建议写在:AssemblyInfo.cs) [assembly: Activation( typeof (ActivatingMvcWeb.MyMvcApplication))] namespace ActivatingMvcWeb { /// <summary> /// 方式2:以实现接口来触发事件 /// [assembly: Activation(typeof(ActivatingWeb.MyApplication))] /// </summary> public class MyMvcApplication : ActivationBase { public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute( "{resource}.axd/{*pathInfo}" ); routes.MapRoute( "Default" , // Route name "{controller}/{action}/{id}" , // URL with parameters new { controller = "Home" , action = "Index" , id = UrlParameter.Optional } // Parameter defaults ); } public override void PreApplicationStart() { // Mvc 不能在网站启动之前初始化 // 但是可以在这里初始化其它程式元件,例如依赖注入等等 } public override void PostApplicationStart() { AreaRegistration.RegisterAllAreas(); RegisterRoutes(RouteTable.Routes); } public override void PreApplicationEnd() { } } } |
运行结果:
另外说明一下:System.Kudy是本人为公司写的一个功能性类库,从之前的KudySharp重新整理并加强的,目前还在整理完善中,大 约在2012年底在公司项目完善时System.Kudy的稳定初版本应该就会发布了,可以免费提供给大家个人或商业使用,但此项目目前是不打算开源的,谢绝索要源码,如果会开源自然就开源的。
下载例子源码:ActivatingWeb.rar ActivatingMvcWeb.rar
请使用vs2010打开项目,本文对你有帮助的话请点下推荐支持,或关注本博客,谢谢。