如何发送非序列化对象作为参数传递给代理方法。 MarshalByRefObject的包装?(Ho

2019-09-18 17:08发布

我在我目前正在修改一个插件架构,使其利用应用程序域。 我在网上找到我的插件和许多例子之间的主要区别在于不是插件运行并发送其结果返回给主应用程序,我的主要应用是一个将信息发送到该插件。

当前标准的,我在一个单独的AppDomain创建加载器实例。 那么它所有的正常初始化,例如加载插件组装。 由于这一点,然后我用装载机的代理来调用从主应用到新的AppDomain中发送数据的方法。

当我尝试调用它有一个参数类型不是可序列化的方法,并且不从MarshalByRefObject的派生出现我的问题。

由于这些类型是从第三方代码,插件指望得到他们,我似乎无法找到一个办法做到这一点。 发现这个问题后( 如何解决“必须是MarshalByRefObject的”如C#?一个好的,但多重继承截肢语言 ),我在想创造某种包装的。 在这里,我的缺点是,我只是不能想出一个办法让一个没有修改第三方代码。

这是我的问题的例子:

// Cant modify this class
class ThirdPartyClass
{
    // The properties are also 3rd party and nonserializable. These are accessed by the plugins.
    public AnotherClass Property1{ get; set; }
    public AnotherClass Property2{ get; set; }

    public ThirdPartyClass(){}
}

class Loader : MarshalByRefObject
{
    private Plugin plugin;

    public Loader()
    {
        Assembly pluginAssembly = Assembly.LoadFrom("Full/Assembly/Path");
        plugin = pluginAssembly.CreateInstance("Full.Plugin.Name") as Plugin;
    }

    public void DoSomething(ThirdPartyClass o)
    {
        ...
        plugin.DoSomethingElse(o);
    }
}

class PluginManager
{
    void Main(ThirdPartyClass o)
    {
        AppDomain pluginAppDomain = AppDomain.CreateDomain("Plugin AppDomain");
        Loader loader = pluginAppDomain.CreateInstanceFromAndUnwrap("Full/Loader/Path", "Full.Loader.Name") as Loader;

        // This is where I would have a problem.
        loader.DoSomething(o);
    }
}

任何帮助将不胜感激。

Answer 1:

你需要有应用程序域与第三方对象交互,它反射回来的另一面? 如果不是(根据您的标题,它听起来就像你不会介意他们可序列化),那么为什么不序列化呢? 我的意思是这样类似的东西:

[Serializable]
class MyThirdPartyClass : ThirdPartyClass, ISerializable
{
    public MyThirdPartyClass()
    {
    }

    protected MyThirdPartyClass(SerializationInfo info, StreamingContext context)
    {
        Property1 = (AnotherClass)info.GetValue("Property1", typeof(AnotherClass));
        Property2 = (AnotherClass)info.GetValue("Property2", typeof(AnotherClass));
    }

    public void GetObjectData(SerializationInfo info, StreamingContext context)
    {
        info.AddValue("Property1", Property1);
        info.AddValue("Property2", Property2);
    }
}

当然也有注意事项这种方法,首先它依赖于你能够派生类,其次它需要你的数据手动序列化(的程度)。 你可以自动在内部字段这是现实,你需要担心和重建的另一边,有效地手动序列化的唯一的事情,使用反射。

你可能已经能够实现的替代选择,但现在看来,这是不是暴露于显影剂更改默认的应用程序域间一个:(



Answer 2:

如果这些都只是正在跨越应用程序域边界,这意味着你没有比一个应用程序域的详细使用它们的情况下,你可以简单地将它们包装在自MarshalByRefObject派生的holder类。

我使用IronScheme的远程代码类似的方法。

问题是,当你真正需要做的不仅仅是持有到该实例。 在这种情况下,你也许可以使用接口挂接所需的方法和公开是通过“持有人”类。



文章来源: How to send nonserializable objects as arguments to a proxy method. MarshalByRefObject wrapper?