MEF 和 ShadowCopying DLL,以便我可以在运行时覆盖它们 [英] MEF and ShadowCopying DLLs so that I can overwrite them at runtime

查看:22
本文介绍了MEF 和 ShadowCopying DLL,以便我可以在运行时覆盖它们的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图停止我的应用程序锁定我的 MEF 插件目录中的 DLL,以便我可以在运行时覆盖程序集(注意,我实际上并没有试图让 MEF 即时重新加载它们,在下一个应用程序启动时很好,我只是不想停止应用程序来进行复制)

I am trying to stop my application locking DLLs in my MEF plugin directory so that I can overwrite the assemblies at runtime (note I'm not actually trying to have MEF reload them on the fly, at the next app start is fine, i just dont want to have to stop the app to do the copy)

我试图通过为我的 mef 加载的程序集创建一个影子复制的应用程序域来做到这一点,如下所示:

I am trying to do this by creating a shadow copied app domain for my mef loaded assemblies as below:

[Serializable]
    public class Composer:IComposer
    {
        private readonly string _pluginPath;
        public Composer(IConfigurePluginDirectory pluginDirectoryConfig)
        {
            _pluginPath = pluginDirectoryConfig.Path;
            var setup = new AppDomainSetup();
            setup.ShadowCopyFiles = "true"; // really??? is bool not good enough for you?
            var appDomain = AppDomain.CreateDomain(AppDomain.CurrentDomain.FriendlyName + "_PluginDomain", AppDomain.CurrentDomain.Evidence, setup);

            appDomain.DoCallBack(new CrossAppDomainDelegate(DoWorkInShadowCopiedDomain));      
        }

        private void DoWorkInShadowCopiedDomain()
        {
            // This work will happen in the shadow copied AppDomain.

            var catalog = new AggregateCatalog();
            var dc = new DirectoryCatalog(_pluginPath);
            catalog.Catalogs.Add(dc);
            Container = new CompositionContainer(catalog);
        }

        public CompositionContainer Container { get; private set; }
    }

然后通过此类上的 CompositionContainer 访问我的 MEF 组件目录.然而,组合容器似乎只在 shadowcopy 域内初始化(这是有道理的),这意味着它在我的应用程序域中为空.我只是想知道是否有更好的方法来做到这一点或某种跨域查询的方法来获取我的 MEF 组件

and then access my MEF component catalog via the CompositionContainer on this class. However the composition container seems to only be initialised inside the shadowcopy domain (which makes sense) and this means that its null in my application domain. I was just wondering if theres a better way to do this or some way to cross domain query to get my MEF components

推荐答案

如果您不想遵循 Dan Bryant 和 zync 的解决方案,您可以创建一个 shell 应用程序,只需在新的 中执行您的应用程序应用域.

If you don't want to follow the solution from Dan Bryant and zync, you could create a shell application that simply executes your application in a new AppDomain.

一种方法是:

  1. 创建一个新的应用程序项目,该项目将作为 shell 应用程序.
  2. 在 shell 应用程序中,创建 AppDomain,启用卷影复制,如果需要,指定将启用卷影复制的目录.
  3. 使用 AppDomain.ExecuteAssembly调用您当前的应用程序.
  1. Create a new application project which will be the shell application.
  2. In the shell application, create the AppDomain, enable shadow copying and if you wish, specify the directory where shadow copying will be enabled.
  3. Use AppDomain.ExecuteAssembly to call your current application.

如果您有一个类库而不是应用程序,您可以尝试以下操作:

If instead of an application you have a class library you can try the following:

  1. 创建一个新的类库项目.
  2. 在新的类库项目中添加如下接口:

  1. Create a new class library project.
  2. Add the following interface to the new class library project:

public interface IRemoteLoader  
{  
    void Load();  
    void Unload();  
}

  • 将此接口的实现添加到需要在新 AppDomain 中执行的类库中.在 LoadUnload 方法中,您应该添加代码以分别执行初始化和清理.使类派生自 MarshalByRefObject.这是 .NET Remoting 在两个 AppDomain 上创建代理对象所必需的.

  • Add an implementation of this interface to your class library that needs to execute in a new AppDomain. In the Load and Unload methods you should add code to perform initialization and cleanup respectively. Make the class derive from MarshalByRefObject. This is needed for .NET Remoting to create proxy objects on both AppDomains.

    创建新的 AppDomain 后,使用 CreateInstanceAndUnwrap 创建第 3 步中加载器类的实例.

    After you create the new AppDomain, use CreateInstanceAndUnwrap to create an instance of the loader class from step 3.

    在第 4 步创建的对象上使用 LoadUnload.

    Use the Load and Unload on the object created from step 4.

    如果您不进行细粒度控制,只需启动/停止就足够了.

    This will be enough if you do not fine-grained control and simply starting/stopping is enough.

    这篇关于MEF 和 ShadowCopying DLL,以便我可以在运行时覆盖它们的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

  • 查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆