【问题标题】:c# Assembly.LoadFrom with dynamic AssemblyResolvec# Assembly.LoadFrom 与动态 AssemblyResolve
【发布时间】:2017-03-30 15:43:17
【问题描述】:

我有点被动态加载插件所困扰:

理论:(插件)特定文件夹中的 Dll:

foreach(string path in Directory.GetFiles(...))
{
    Assembly myPlugin = Assembly.LoadFrom(path);
    foreach(Type type in myPlugin.GetTypes().Where(t => typeof(myPluginBaseClass).isAssignableFrom(t)))
    {
        Activator.CreateInstance(type);
    }
}

到目前为止一切顺利。 现在这些程序集中的附加引用存在问题,可以通过catch(ReflectionTypeLoadException)(删除所有空类型)和AppDomain.CurrentDomain.AssemblyResolve += ...(手动查找那些丢失的dll)来解决

现在的问题是:引用的缺失程序集特定于每个已实现的插件,因此我需要在每个插件中实现单独的搜索行为。到目前为止我的想法/解决方案:

  • 在我的主应用程序中拥有所有可能的 DLL 目录的全局列表 -> 愚蠢,因为这不允许在不更改主应用程序代码的情况下添加更多插件
  • 在每个插件中都有一个(非静态的)特定 dll 路径字典 -> 可以通过 myPluginBaseClass 使用虚拟/抽象来强制;但是在创建实例之前无法访问(那些AssemblyResolveEvents 被触发),所以没有帮助
  • 在每个插件中都有一个包含特定 dll 路径的(静态)字典 -> 可以在实例化之前使用反射读取,但我无法将其添加到我的 myPluginBaseClass 作为定义的模板,因此可能会出错
  • 为每个插件创建一个单独的域并让他们处理自己的AssemblyResolveEvent -> 但是如何?

希望你能帮上忙!

提前致谢! 罗宾

【问题讨论】:

    标签: c# plugins reflection .net-assembly assemblyresolve


    【解决方案1】:

    创建域似乎是插件模式的适当解决方案。

    你真的不需要定义AssemblyResolve,你可以简单的配置AppDomain可以找到依赖的目录。

    https://msdn.microsoft.com/fr-fr/library/system.appdomainsetup.applicationbase(v=vs.110).aspx

    【讨论】:

    • 感谢您的回复!似乎创建一个新的 AppDomain 似乎是一个好方法。尽管问题仍然存在,我只在运行时知道我丢失的程序集所在的位置(因为我需要从注册表交换这些信息和/或检查多种可能性)。因此,每个插件可以有多个目录:Main.exe 的基本目录 (AppDommain.CurrentDomain) + Subdir1 + Subdir2 + 那些额外的动态位置...
    猜你喜欢
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-01
    • 2023-04-08
    • 1970-01-01
    相关资源
    最近更新 更多