asp.net动态加载程序集

时间:2013-10-09 10:27:27

标签: asp.net plugins webforms mef .net-assembly

我正在尝试使用MEF为asp.net webforms制作某种插件系统。

到目前为止,我已经找到了一个解决方案,主机网站将在其插件文件夹中搜索,以加载名为模块的其他网站。模块(插件)只是另一个网站项目,因此它的 bin 子文件夹中有自己的程序集。

您当然已经知道,ASP.NET应用程序不会在其 bin 文件夹之外加载dll。因此,如果我尝试访问模块页面(例如: plugins / MyModule / Page.aspx )。我会收到一条错误消息,指出服务器无法加载程序集 MyModule 。我可以将模块的程序集放在主 bin 文件夹中,一切都会正常工作,但我想将所有模块文件保存在同一个文件夹中。

所以我正在寻找一种在 bin 文件夹之外加载程序集的方法。我已经尝试搞乱web.config文件,但无法提供可行的解决方案。

然后我来到 BuildManager 类并编写了这段代码:

string pluginPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "plugins");
foreach (string f in Directory.GetDirectories(pluginPath))
{
    string binPath = Path.Combine(f, "bin");
    if (Directory.Exists(binPath))
    {
        foreach (String file in Directory.GetFiles(binPath, "*.dll"))
        {
            Assembly a = Assembly.LoadFrom(file);
            BuildManager.AddReferencedAssembly(a);
        }
    }
}

插件文件夹中搜索包含 bin 文件夹的任何其他子文件夹,并使用 BuildManager 加载相应的程序集。要使此代码有效,我必须在 global.aspx 程序集的 PreApplicationStartMethod 中调用它。

现在当我导航到插件页面(插件/ MyModule / Page.aspx )时,它不会给我以前的错误,但页面是空白的。我检查了源代码,没有html,没有。我试图调试页面,但从未调用 Page_Load 方法。所以我想某种方式 Page.aspx 背后的代码永远不会被调用。

编辑:

所以在搜索了一下后,我在那里找到了一个解决方案:

BuildManager Resolving Page Inheritance

当我加载模块程序集时,我将其引用存储在dictionnay中。 然后在 AppDomain.CurrentDomain.AssemblyResolve 的事件处理程序中,我返回相应的模块程序集。

1 个答案:

答案 0 :(得分:7)

我遇到了同样的问题。我通过解决汇编修复如下

protected virtual void Application_Start(object sender, EventArgs e)
    {

        //...

        AppDomain.CurrentDomain.AssemblyResolve += CurrentDomain_AssemblyResolve;
    }

    System.Reflection.Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args)
    {
        var currentAssemblies = AppDomain.CurrentDomain.GetAssemblies();

        foreach (var assembly in currentAssemblies)
        {
            if (assembly.FullName == args.Name || assembly.GetName().Name == args.Name)
            {
                return assembly;
            }
        }

        return null;
    }