重点有以下几个:
1、必须从VirtualPathProvider类继承
2、IsAppResourcePath方法是用来判断是否为我们定义的路径格式:~/MyUserControl/Test.Control.dll/,下面调用的时候就使用这个路径
3、注意GetCacheKey方法:
public override string GetCacheKey(string virtualPath)
{
if (IsAppResourcePath(virtualPath))
{
return null;
}
else
{
return Previous.GetCacheKey(virtualPath);
}
}
{
if (IsAppResourcePath(virtualPath))
{
return null;
}
else
{
return Previous.GetCacheKey(virtualPath);
}
}
这里当符合条件时一定要返回null,如果返回"",会导致所有的用户控件都使用一个key值,从而所有的用户控件都显示同样的内容了。如果返回其他非空字符,会报异常(它会去查找cache,我们是没有的)
另外所有的方法当不符合我们的条件时一定要调用 Previous.**** 因为系统中可能有多个虚拟文件提供程序的。
4、GetCacheDependency方法:
if (IsAppResourcePath(virtualPath))
{
string path = HttpRuntime.AppDomainAppPath + virtualPath.Substring(1);
return new System.Web.Caching.CacheDependency(path);
}
{
string path = HttpRuntime.AppDomainAppPath + virtualPath.Substring(1);
return new System.Web.Caching.CacheDependency(path);
}
这个方法是用来决定Cache的使用的,如果返回null,会导致性能严重下降,每次调用用户控件时都会重新编译,这里返回的当前路径(需要在网站目录下再建立子目录:MyUserControl\Test.Control.dll),这个目录下是空的,这样当每次取Cache时都会认为我们的ascx没有修改,不需要重新编译。
5、在GetFile方法中我们返回的是一个AssemblyResourceVirtualFile类:
class AssemblyResourceVirtualFile : VirtualFile
{
string path;
public AssemblyResourceVirtualFile(string virtualPath)
: base(virtualPath)
{
path = VirtualPathUtility.ToAppRelative(virtualPath);
}
public override System.IO.Stream Open()
{
string[] parts = path.Split('/');
string assemblyName = parts[2];
string resourceName = parts[3];
assemblyName = Path.Combine(HttpRuntime.BinDirectory, assemblyName);
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(assemblyName);
if (assembly != null)
{
return assembly.GetManifestResourceStream(resourceName);
}
return null;
}
}
{
string path;
public AssemblyResourceVirtualFile(string virtualPath)
: base(virtualPath)
{
path = VirtualPathUtility.ToAppRelative(virtualPath);
}
public override System.IO.Stream Open()
{
string[] parts = path.Split('/');
string assemblyName = parts[2];
string resourceName = parts[3];
assemblyName = Path.Combine(HttpRuntime.BinDirectory, assemblyName);
System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom(assemblyName);
if (assembly != null)
{
return assembly.GetManifestResourceStream(resourceName);
}
return null;
}
}
这个类的目的就是从我们的dll中读出资源文件。