微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

asp.net-mvc-3 – 具有ASP.NET MVC3和嵌入式Razor视图的插件框架

我正在使用Razor视图为ASP.NET MVC3设计一个插件框架,并且让嵌入式视图正常工作时出现问题.

插件框架设计具有以下功能

>每个插件都有自己的模型,控制器和视图.视图是嵌入式资源,控件派生自PluginController类
>插件具有对定义PluginController基类的共享类库的依赖引用
>承载插件的“shell”Web应用程序在设计时不能保留对任何插件的引用,因为它在设计时不知道它具有哪些插件.
>插件dll被丢弃在shell应用程序的一个文件夹中,这不是/ bin文件
> shell负责:

发现插件(使用反射)
>注册所有控制器(我正在使用Spring.Net)
>创建到控制器的路由
>通过自定义的VirtualPathProvider为剃须刀文件(cshtml)服务

现在一切正常,除非嵌入视图引用了插件dll中的类型.然后我得到臭名昭着的错误(遗漏的名字):

命名空间'[MyPluginSolution]’中不存在类型或命名空间名称[插件])(您是否缺少程序集引用?)

这样做的原因是调用运行时编译剃刀视图的csc编译器只能从bin文件夹和GAC获取dll引用.

我也尝试使用this technique预编译视图,但最终给出了相同的结果,因为运行时坚持编译预编译的剃刀视图的包装器.

我当然可以把插件dll放在/ bin文件夹中,但我的问题是:

有没有办法在非bin(和非GAC)文件夹中注册dll,并将其视为“一级公民”,以便它们可以被剃刀视图使用?

解决方法

好的,解决方案是使用 this article发现的.

首先我用PreApplicationStartMethod创建一个类.此方法扫描插件文件夹,并将dll复制到AppDomain.DynamicDirectory.

然后使用BuildManager.AddReferencedAssembly加载这些dll的每个.

而且,强大的剃刀视图编译精美.请看代码

[assembly: PreApplicationStartMethod(typeof(MySolution.PluginHandler.PluginActivator),"Initialize")]
namespace MySolution.PluginHandler
{
    public class PluginActivator
    {
        private static readonly DirectoryInfo PluginFolderInfo;

        static PluginActivator() {
            PluginFolderInfo = new DirectoryInfo(HostingEnvironment.MapPath("~/plugins"));
        }

        public static void Initialize() {
            copyPluginDlls(PluginFolderInfo,AppDomain.CurrentDomain.DynamicDirectory);
            LoadpluginAssemblies(AppDomain.CurrentDomain.DynamicDirectory);
        }

        private static void copyPluginDlls(DirectoryInfo sourceFolder,string destinationFolder)
        {
            foreach (var plug in sourceFolder.GetFiles("*.dll",SearchOption.AllDirectories)) {
                if (!File.Exists(Path.Combine(destinationFolder,plug.Name))) {
                    File.copy(plug.FullName,Path.Combine(destinationFolder,plug.Name),false);
                }
            }
        }

        private static void LoadpluginAssemblies(string dynamicDirectory)
        {
            foreach (var plug in Directory.GetFiles(dynamicDirectory,"*.dll",SearchOption.AllDirectories)) {
                Assembly assembly = Assembly.Load(AssemblyName.GetAssemblyName(plug));
                BuildManager.AddReferencedAssembly(assembly);
            }
        }
    }
}

我希望这可以帮助其他想要使用这些新技术创建一个干净的插件框架的程序员.

原文地址:https://www.jb51.cc/aspnet/250217.html

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐