【问题标题】:Replaceable assemblies for plugin插件的可替换组件
【发布时间】:2014-02-06 20:54:15
【问题描述】:

我们正在尝试热交换(更新)程序集,正常的工作流程是我们进行一些更改,构建程序集,进行一些更改并再次构建,在理想情况下,主机应用程序将获得新版本的程序集(使用更新的类型)。

这是我们的小型插件加载器类:

public class PluginLoader<T>
{
    private CompositionContainer _compositionContainer;
    private RegistrationBuilder _registrationBuilder;
    private DirectoryCatalog _catalog;

    [ImportMany(AllowRecomposition = true)]
    public IList<T> Plugins { get; set; }

    public PluginLoader(string pluginsDirectory)
    {
        Plugins = new List<T>();
        SetShadowCopy();

        _registrationBuilder = new RegistrationBuilder();
        _registrationBuilder
           .ForTypesDerivedFrom(typeof(T))
           .SetCreationPolicy(CreationPolicy.NonShared)
           .Export<T>();

        _catalog = new DirectoryCatalog(pluginsDirectory, _registrationBuilder);

        _compositionContainer = new CompositionContainer(_catalog, CompositionOptions.DisableSilentRejection);
        _compositionContainer.ComposeParts(this);
    }

    public void Reload()
    {
        _catalog.Refresh();
        _compositionContainer.ComposeParts(this);
    }

    private static void SetShadowCopy()
    {
        AppDomain.CurrentDomain.SetShadowCopyFiles();
        AppDomain.CurrentDomain.SetCachePath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "ShadowCopyCache"));
        AppDomain.CurrentDomain.SetShadowCopyPath(Path.Combine(AppDomain.CurrentDomain.SetupInformation.ApplicationBase, "Plugins"));
    }
}

我们有代码可以使用 FileSystemWatcher 识别放入 plugins 文件夹的新插件,并在发生这种情况时调用 Reload,但实际上并未加载新版本的程序集。 有什么指点吗?

注意事项:

  • 没有识别出新的或删除的类型,就好像它根本不识别新的程序集一样。
  • 我们检查了,也没有合成和其他错误,所以我们有点失落:D
  • 重要的是要注意,如果我们使用不同的编译器 (Roslyn) 构建相同的无法识别的程序集,那么它就会被识别(这表明没有任何设置错误,只是程序集需要有所不同)李>

【问题讨论】:

    标签: c# mef system.componentmodel


    【解决方案1】:

    SetShadowCopy 中调用的方法已弃用。您无法在现有 AppDomain 上启用 ShadowCopy。有关如何在新 AppDomain 上启用 ShadowCopy 的示例,请查看answer

    DirectoryCatalog.Refresh 会更新已加载的程序集。它只检查文件删除和添加。看看这个answer 以获得粗略的解决方法。请注意,我不确定这种方法是线程安全的还是生产就绪的,因为我只测试了简单的场景。另一种方法是创建自己的 DirectoryCatalog,它也可以处理更新。 MEF 源代码可用(与框架的其余部分一样)。棘手的部分是线程安全,因为 DirectoryCatalog 实现使用 Microsoft 的内部类进行锁定。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-12-08
      • 1970-01-01
      • 1970-01-01
      • 2014-06-23
      • 1970-01-01
      • 1970-01-01
      • 2020-01-31
      相关资源
      最近更新 更多