我正在为一个插件系统工作Asp.netMVC 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>
总而言之。
这对于强类型场景是有意义的,因为类型在动态加载的dll中,所以viewengine不会知道它,即使dll在bin中也是如此。有没有办法在应用程序启动时加载类型?考虑用MEF代替我定制的Structuremap解决方案。你怎么认为?