我正在从程序集名称的数据库表中动态加载程序集,程序集名称将规则插入规则引擎中。我们的想法是,我们可以通过开发新规则来扩展功能,而不必重新编译和部署整个套件。
有一个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,但是当它尝试进一步实例化它的两行代码时,便找不到了。
答案 0 :(得分:0)
最终的解决方法很简单:
var ruleAssembly = Assembly.LoadFrom(rule.AssemblyName");
从LoadFrom()到Load()的切换就足够了。我相信这与程序集加载到的上下文有关。