VirtualPathProvider注册的问题

MSDN里有描述,VirtualPathProvider只允许在两个地方注册:

1. App_Code目录中任意类的AppInitialize静态方法。

2. Global.asax中的Application_Start方法中。

而我想知道是,有没有什么办法,可以将VirtualPathProvider注册的代码放入外部的dll中,在不需要在App_Code和Global.asax中添加任何代码的情况下,将VirtualPathProvider通过外部dll自动注册。或者,只通过web.config配置也行。

VirtualPathProvider的作用参考:http://www.cnblogs.com/coderzh/archive/2010/01/26/Sharing-Master-Pages-By-DLL.html

App_Code AppInitialize

在App_Code目录里,任意类,实现一个AppInitialize静态方法,原型:

public static void AppInitialize()

这个方法,将会在Web应用程序初始时自动被调用。因此,考虑在外部dll中定义的AppInitialize方法是否会被执行?

遗憾的是,AppInitialize方法必须在App_Code目录不可。App_Code目录是一个非常特殊的目录,特殊到很多规则你都不知道,ASP.NET对这个目录的文件会做一些特殊的处理。就比如AppInitialize静态方法的执行规则:

1. AppInitialize静态方法必须是在App_Code目录下。

2. AppInitialize静态方法在App_Code目录下不允许被定义两次。

如果AppInitialize在App_Code的两个类中都有定义,比如:

public class SomeClassOne
{
    
public static void AppInitialize()
    {
        HostingEnvironment.Cache[
"InitializationTimeOne"= DateTime.Now;
    } 
}

public class SomeClassTwo
{
    
public static void AppInitialize()
    {
        HostingEnvironment.Cache[
"InitializationTimeTwo"= DateTime.Now;
    } 
}


编译时,将会出现编译错误:

The AppInitialize method is defined both in 'App_Code.SomeClassOne' and in 'App_Code.SomeClassTwo'.


AppInitialize方法在编译时就被特殊处理了。推断,AppInitialize方法想在外面的dll中执行几乎是不可能的。

Application_Start 

Global.asax继承自HttpApplication,有很多事件(event)可以通过自定义的HttpModule挂上去,比如:AuthenticateRequest,EndRequest。因此,如果HttpApplication有一个类似ApplicationStart的Event,那么我就可以在外部dll中实现一个自定义的HttpModule,然后再Init函数中,将VirtualPathProvider注册的代码挂到ApplicationStart事件中。这样,要做的仅仅是在Web.config中将自定义的HttpModule加进去。可惜,Application_Start并不提供挂载事件。

Application_Start调用的一些细节参考:http://www.dotnet247.com/247reference/msgs/12/62243.aspx

Web.config

没有任何迹象表明,允许在Web.config中配置VirtualPathProvider的注册。

总结:

尝试的各种方法都失败了,没办法做到不需要在App_Code和Global.asax中添加任何代码的情况下,通过外部dll将VirtualPathProvider自动注册。还是老老实实在每个需要用到VirtualPathProvider的工程,在Global.asax的Application_Start方法中添加如下方法:

protected void Application_Start(object sender, EventArgs e)
{
    CustomVirtualPathProvider vpp 
= new CustomVirtualPathProvider();
            
    HostingEnvironment.RegisterVirtualPathProvider(vpp);
}


谁有别的办法吗?

posted @ 2010-01-31 11:38  CoderZh  阅读(3025)  评论(6编辑  收藏  举报