Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为什么在使用对象远程处理MarshalByRefbj时使用委托?_C#_Delegates_Marshalling - Fatal编程技术网

C# 为什么在使用对象远程处理MarshalByRefbj时使用委托?

C# 为什么在使用对象远程处理MarshalByRefbj时使用委托?,c#,delegates,marshalling,C#,Delegates,Marshalling,我的应用程序允许插件,我有一个插件必须继承的核心类(MarshallByRefbj),这个类提供各种功能。现在我的问题是,当这个类在主应用程序域上实例化并传递给不同应用程序域中的插件时,在这种情况下使用委托有什么好处: public class Core : MarshalByRefObject { public void DoSomething() { MyMainApp.Delegate1("SomeMethod", "Test"); } } 如您

我的应用程序允许插件,我有一个插件必须继承的核心类(MarshallByRefbj),这个类提供各种功能。现在我的问题是,当这个类在主应用程序域上实例化并传递给不同应用程序域中的插件时,在这种情况下使用委托有什么好处:

public class Core : MarshalByRefObject
{
    public void DoSomething()
    {
         MyMainApp.Delegate1("SomeMethod", "Test");
    }
}
如您所见,我的核心类在MyMainApp上调用委托方法。我也可以只做
MyMainApp.SomeMethod(“测试”)


然而,在许多关于远程处理和插件系统如何工作的在线示例中,每个人似乎都在使用代理。有什么具体的原因吗?有人能给我举个更实际的例子来说明原因吗

大多数情况下,用户界面中的控件都是由主线程创建的,除非您有意在另一个线程中创建它们。这里是重要的一点:只有创建控件的线程才能访问该控件。

如果您直接调用
DoSomething
,并且
DoSomething
中的代码希望与UI控件交互,则将不允许该操作,您将获得异常
MyMainApp.Delegate1(“DoSomething”
相当于:请在主线程上执行指定的方法。现在它可以访问UI控件


还有其他原因,但这是需要记住的最重要的一点。有关更多信息,请参阅。

其中一个好处是,传递给
MyMainApp.Delegate1的信息被序列化,以便从插件appdomain传输到主appdomain。
Delegate1
方法将执行
DoSomething
>在主域中。它们不共享内存(因此无法直接访问对象实例)。因此,您可以在另一个appdomains上动态运行方法。如果通过反射完成,则插件可能能够运行未列出的方法

我不希望使用这种类型的构造,因为调用方法时没有编译时检查。我希望使用卫星程序集中的接口。(为了防止主appdomain获取对插件程序集的引用/加载插件程序集,因此无法再卸载插件程序集)


另一件事: 如果您直接调用
MyMainApp.SomeMethod(“test”)
。这意味着插件必须知道插件加载程序的定义。这意味着您(从插件)与“父”应用程序(s版本)紧密耦合。这使得整个插件结构“无用”。您可以通过在MyMainApp上实现一个
ISupportSomeMethod
接口来解决这一问题,该接口是在一个卫星程序集中定义的,该卫星程序集由mainapp和插件使用。如果您的MyMainApp没有实现
ISupportSomeMethod
接口,则插件与这样你的
MyMainApp
就可以支持多种插件结构


在这种情况下,您更喜欢事件结构。因为子对象希望触发其父对象的方法。太糟糕了,跨域事件调用没有用,因为您的主模块将加载程序集并且无法卸载。您可以为此编写代理类