我有一个大型应用程序,它使用COM通过.net远程处理从Web层调用到中间层。 在此模式下启动和运行速度非常慢。 COM边界的两边都是我们的代码。
我希望能够(可选)在一个进程中运行它。 相当一部分行为依赖于ServicedComponents的调用,其所有参数都被序列化,并且除非参数是'ref'参数,否则对组件内部对象所做的更改不会泄漏。
我目前计划将这个双进程应用程序强制转换为单个进程,而无需更改太多代码,方法是使用带有自定义.net远程处理的假中间层边界。
如果我改变所有:
class BigComponent : ServicedComponent {
...
}
到
[FakeComponent]
class BigComponent : ContextBoundObject {
...
}
然后我可以编写一个自定义ContextAttribute来伪造进程边界并使参数自行序列化:
即
[AttributeUsage(AttributeTargets.Class)]
public class FakeComponentAttribute :
ContextAttribute,
IContributeServerContextSink
{
... lots of stuff here
}
根据http://msdn.microsoft.com/en-us/magazine/cc164165.aspx
现在这个工作正常,到目前为止,我可以拦截对这些类的方法的所有调用。 但是,我只能在IMessageSink.ProcessMessage调用中查看IMethodCallMessage.Args - 我似乎无法用我选择的对象替换它们。
每当我更改IMethodCallMessage.Args数组中的条目时,我的更改都会被忽略。从我在Reflector中可以看出,这个接口是运行时本身的本机对象的包装器,我不能写入这个对象,只需阅读它。
如何在.net remoting中修改方法调用的参数?
我需要实现自己的频道吗?是否有一个“本地”频道教程,我可以来自哪里?
我的目标是让这些组件像远程对象一样(因为它们的所有args在进入方法的过程中被序列化,并且它们的返回值在出路时被序列化),但远程端点在内部同样的过程。
答案 0 :(得分:0)
我没有找到一种方法来编辑参数数组,因为它通过IMessageSink
。
最后,我不得不让参数对象类知道这个问题,并实现一个新的接口IFakeRemotingAware
。这允许复杂对象参数在使用远程处理时使用远程处理来模拟该行为时,由于序列化/反序列化而表现出pass-by-val行为。
接口有两种方法:EnteringFakeRemote
使对象缓存其状态的本地副本,LeavingFakeRemote
使对象从缓存中恢复其状态。