首页 > 解决方案 > 动态加载的程序集 - MVC 和 WCF 行为不同

问题描述

我正在从程序集名称的数据库表中动态加载程序集,它将规则插入规则引擎。这个想法是我们可以通过开发新规则来扩展功能,而无需重新编译和部署整个套件。

有一个 MVC Web 应用程序和一个 WCF 桌面应用程序,它们共享大量代码,包括我在这里描述的 RulesRunner 类。

此代码在 RulesRunner 类的构造函数中

        rules = rulesEngineRepository.GetRules(x => x.Enabled);
        foreach (var rule in rules)
        {
            var ruleAssembly = Assembly.LoadFrom($"{rule.AssemblyName}.dll");
            var installerType = ruleAssembly.GetType("RulesEngine.Rules.RulesInstaller");
            var installer = Activator.CreateInstance(installerType) as IWindsorInstaller;
            container.Install(installer);
        }

RulesRunner 类不是动态加载的,它被编译为 MVC 和 WCF 代码中的普通引用。

在 WCF 案例中,这一切都完全按预期工作。加载程序集,创建一个实例,当规则引擎在其他地方触发时,它完美地使用以这种方式加载的规则。

在 MVC Web 应用程序中,此代码从 Activator.CreateInstance 行返回 null,因此在调用它时会进一步失败。我一生都无法弄清楚这里发生了什么不同。

如果我在调用 container.Install(installer) 后检查变量,我可以看到变量安装程序报告“'installer' 抛出了 'System.IO.FileNotFoundException' 类型的异常”。

但是但是但是...installerType 具有所有正确的信息和值。就像它找到了执行 LoadFrom 的 DLL,但是当它尝试进一步实例化它的两行代码时就找不到它了。

标签: .netwcfmodel-view-controllerreflection

解决方案


The fix to this was quite simple in the end:

var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");

The switch from LoadFrom() to Load() was all it needed. I believe this is to do with the context that the assembly is loaded into.


推荐阅读