我正在为Asp.net MVC 2开发一个插件系统。我有一个包含控制器和视图的dll作为嵌入式资源。
我使用StructureMap扫描控制器的插件dll然后我可以将它们拉出来并在请求时实例化它们。这很好用。然后我有一个VirtualPathProvider,我改编自this post
public class AssemblyResourceProvider : VirtualPathProvider
{
protected virtual string WidgetDirectory
{
get
{
return "~/bin";
}
}
private bool IsAppResourcePath(string virtualPath)
{
var checkPath = VirtualPathUtility.ToAppRelative(virtualPath);
return checkPath.StartsWith(WidgetDirectory, StringComparison.InvariantCultureIgnoreCase);
}
public override bool FileExists(string virtualPath)
{
return (IsAppResourcePath(virtualPath) || base.FileExists(virtualPath));
}
public override VirtualFile GetFile(string virtualPath)
{
return IsAppResourcePath(virtualPath) ? new AssemblyResourceVirtualFile(virtualPath) : base.GetFile(virtualPath);
}
public override CacheDependency GetCacheDependency(string virtualPath, IEnumerable virtualPathDependencies,
DateTime utcStart)
{
return IsAppResourcePath(virtualPath) ? null : base.GetCacheDependency(virtualPath, virtualPathDependencies, utcStart);
}
}
internal class AssemblyResourceVirtualFile : VirtualFile
{
private readonly string path;
public AssemblyResourceVirtualFile(string virtualPath)
: base(virtualPath)
{
path = VirtualPathUtility.ToAppRelative(virtualPath);
}
public override Stream Open()
{
var parts = path.Split('/');
var resourceName = Path.GetFileName(path);
var apath = HttpContext.Current.Server.MapPath(Path.GetDirectoryName(path));
var assembly = Assembly.LoadFile(apath);
return assembly != null ? assembly.GetManifestResourceStream(assembly.GetManifestResourceNames().SingleOrDefault(s => string.Compare(s, resourceName, true) == 0)) : null;
}
}
VPP似乎也运作良好。找到视图并将其拉出到流中。然后我收到一个解析错误Could not load type 'System.Web.Mvc.ViewUserControl<dynamic>'.
,我在前面的可插入视图示例中找不到这个错误。为什么我的观点在这个阶段不能编译?
感谢您的帮助,
伊恩
修改
更接近答案,但不清楚为什么事情没有编译。根据评论,我检查了版本,一切都在V2,我相信动态是在V2引入,所以这很好。我甚至没有安装V3,所以不能这样。然而,如果我完全删除<dynamic>
,我有了渲染的视图。
所以VPP可以工作,但前提是视图不是强类型或动态的
这对强类型场景有意义,因为类型在动态加载的dll中,因此即使dll位于bin中,viewengine也不会意识到它。有没有办法在app start加载类型?考虑使用MEF而不是我的定制Structuremap解决方案。你觉得怎么样?
答案 0 :(得分:2)
允许解析强类型视图的设置在〜/ Views / Web.Config中。当视图引擎使用虚拟路径提供程序时,它不在视图文件夹中,因此不会加载这些设置。
如果将Views / Web.Config的pages节点中的所有内容复制到根Web.Config,则可以正确解析强类型视图。
答案 1 :(得分:1)
尝试将Views / Web.config的内容直接添加到特定位置下的主web.config中,例如用于处理〜/ page / xxx等虚拟路径。在此处查看更多详细信息:http://blog.sergkazakov.com/2011/01/aspnet-strongly-typed-view-and-virtual.html
答案 2 :(得分:0)
有没有办法在app start加载类型?
是的,您可以使用BuildManager.AddReferencedAssembly(assembly),其中assembly
是包含所请求类型的PreApplicationStartMethodAttribute。所以,一旦你使用MEF,最后一个应该很容易,但要注意,一切都应该在Application_Start
之前完成,所以你可能希望使用Fisher Yates shuffle。