【问题标题】:inter-AppDomain communication and interfacesAppDomain 间通信和接口
【发布时间】:2013-09-12 18:42:45
【问题描述】:

我正在寻找一种将组件(基于第 3 方 dll)隔离在可卸载的单独 AppDomain 中的方法。我的计划是使用基于CreateInstanceAndUnwrapMarshalByRefObject 的对象与组件进行通信。

问题是,为了在主程序集中使用从MarshalByRefObject 派生的对象,它必须引用组件 dll,我试图避免这种情况。我想我可以通过接口解耦它

class MyObject: MarshalByRefObject, IMyObject
{
}

但我无法将从CreateInstanceAndUnwrap 返回的对象转换为IMyObject(因为它实际上是一个代理,而不是我猜的真实对象?)。

我是否遗漏了什么,或者这无法完成,唯一的答案是 WCF?

更新: 我遇到的实际问题是 IMyObject 被定义了两次:我将文件包含在主程序集中和组件程序集中。这样我得到一个异常“无法将透明代理转换为类型”。当我只使用从两个程序集中引用的一个接口/类定义时,它可以正常工作(正如 Will 建议的和我上面描述的)。

【问题讨论】:

    标签: c# interface marshalling appdomain


    【解决方案1】:

    呃,接口有点烂。

    放弃它并使用继承自 MBRO 的抽象基类。

    public abstract class MyObject : MarshalByRefObject
    {
        protected MyObject() : base() {}
        public abstract void LoadPluginAssemblyLol();
        public abstract void ExecuteSuperCollider();
    }
    

    将其拉回边界并以这种方式控制插件。另外,请记住不要在类型上公开事件(事件订阅者在您没有意识到的情况下被拉过边界)并且您可能应该只接受方法参数并具有原始值或严格控制的返回值,这样您就不会意外地以在您的主域中加载的 dll。

    您会遇到的另一个问题是您必须管理通过 ISponsor 实现代理的对象的生命周期。否则,主机域中的实例会在 10 分钟后被收集。

    至于使用 MyObject,你会...

    // 假设一个实现,例如 'class MyObjectImplementation : MyObject {...}'

    var type = typeof(MyObjectImplementation);
    var newDomain = CreateNewAppDomainKthx();
    var controller = newDomain
        .CreateInstanceAndUnwrap(
            type.Assembly.FullName, 
            type.FullName) as MyObjectImplementation;
    controller.LoadPluginAssemblyLol();
    controller.ExecuteSuperCollider();
    

    【讨论】:

    • 感谢您的提示!我可以这样做,但是如何通过 CreateInstanceAndUnwrap 以某种方式创建 MyObject?
    • 好吧,使用例如类型typeof(MyObjectImplementation) 表示我需要从主程序集中引用该组件。我试过CreateInstanceAndUnwrap(..., "MyObjectImplementation") as MyObject,它似乎工作正常。我发现我的项目存在问题,修复后界面现在也可以正常工作。在我的情况下,ISponsor 应该不是问题,但非常有用,再次感谢。
    猜你喜欢
    • 1970-01-01
    • 2019-05-31
    • 1970-01-01
    • 2011-07-13
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多