因此,我在上面J Wynia的示例中做了一些尝试。非常感谢顺便说一句。
我进行了更改,以便VirtualPathProvider的扩展使用静态构造函数创建系统中各个dll中所有以.aspx结尾的可用资源的列表。这很费力,但只有我们只做一次。
这可能完全滥用了应该同时使用VirtualFiles的方式;-)
您最终得到:
私有静态IDictionary resourceVirtualFile;
字符串是虚拟路径。
下面的代码对.aspx文件的命名空间进行了一些假设,但是在简单的情况下仍然可以使用。令人高兴的是,您不必创建从资源名称创建的复杂视图路径。
class ResourceVirtualFile : VirtualFile
{
string path;
string assemblyName;
string resourceName;
public ResourceVirtualFile(
string virtualPath,
string AssemblyName,
string ResourceName)
: base(virtualPath)
{
path = VirtualPathUtility.ToAppRelative(virtualPath);
assemblyName = AssemblyName;
resourceName = ResourceName;
}
public override Stream Open()
{
assemblyName = Path.Combine(HttpRuntime.BinDirectory, assemblyName + ".dll");
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(assemblyName);
if (assembly != null)
{
Stream resourceStream = assembly.GetManifestResourceStream(resourceName);
if (resourceStream == null)
throw new ArgumentException("Cannot find resource: " + resourceName);
return resourceStream;
}
throw new ArgumentException("Cannot find assembly: " + assemblyName);
}
private static string CreateVirtualPath(string AssemblyName, string ResourceName)
{
string path = ResourceName.Substring(AssemblyName.Length);
path = path.Replace(".aspx", "").Replace(".", "/");
return string.Format("~{0}.aspx", path);
}
public static IDictionary<string, VirtualFile> FindAllResources()
{
Dictionary<string, VirtualFile> files = new Dictionary<string, VirtualFile>();
string[] assemblyFilePaths = Directory.GetFiles(HttpRuntime.BinDirectory, "*.dll");
foreach (string assemblyFilePath in assemblyFilePaths)
{
string assemblyName = Path.GetFileNameWithoutExtension(assemblyFilePath);
Assembly assembly = Assembly.ReflectionOnlyLoadFrom(assemblyFilePath);
string[] resourceNames = assembly.GetManifestResourceNames();
foreach (string resourceName in resourceNames)
{
if (resourceName.EndsWith(".aspx"))
{
string virtualPath = CreateVirtualPath(assemblyName, resourceName);
files.Add(virtualPath, new ResourceVirtualFile(virtualPath, assemblyName, resourceName));
}
}
}
return files;
}
}
然后,您可以在扩展的VirtualPathProvider中执行以下操作:
private bool IsExtended(string virtualPath)
{
String checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
return resourceVirtualFile.ContainsKey(checkPath);
}
public override bool FileExists(string virtualPath)
{
return (IsExtended(virtualPath) || base.FileExists(virtualPath));
}
public override VirtualFile GetFile(string virtualPath)
{
string withTilda = string.Format("~{0}", virtualPath);
if (resourceVirtualFile.ContainsKey(withTilda))
return resourceVirtualFile[withTilda];
return base.GetFile(virtualPath);
}