首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> .NET 網頁程式設計 >> C# >> 關於C#

Remoting 基礎原理與擴展機制 (中):利用 ChannelSinkProvider 注入 MessageSink

     編輯:關於C#

背景

上篇介紹透過組態檔自訂 ChannelSinkProvider 將 ChannelSink 加入 Pipeline,但只能操作已序列化的資料流。若要攔截原始訊息物件 (修改參數/回傳值、前後置邏輯),需在格式化器前注入 MessageSink,這正是 AOP 核心目標。

利用 IClientChannelSinkProvider 注入 MessageSink

IClientChannelSinkProvider 回傳 IClientChannelSink,但 SoapClientFormatterSink 同時實作 IMessageSink 與 IClientChannelSink (後者方法拋 NotSupportedException),證明可「偽裝」成 ChannelSink 實為 MessageSink。

public class CustomMessageSink : IMessageSink, IClientChannelSink
{
    public IMessage SyncProcessMessage(IMessage msg)
    {
        ((IMethodMessage)msg).LogicalCallContext.SetData("MyName", "idior");
        return _nextSink.SyncProcessMessage(msg);
    }
    // IClientChannelSink 方法全拋 NotSupportedException
}

Pipeline 實際結構

Pipeline 非單一鏈表,而是抽象概念。RealProxy 內部維護 IClientChannelSink 鏈表 (透過 Next 屬性),首節點存於 _identity.ChannelSink。首次呼叫時 RemotingProxy.InternalInvoke 呼叫 RemotingServices.CreateEnvoyAndChannelSinks 建立 EnvoySink 鏈與 ChannelSink 鏈,後者首元素型別為 IMessageSink,最終經 SetEnvoyAndChannelSinks 存入 _identity._channelSink。

internal virtual IMessage InternalInvoke(IMethodCallMessage req, bool useDispatch, int callType)
{
    if (identity.ChannelSink == null)
    {
        IMessageSink envoySink, channelSink;
        RemotingServices.CreateEnvoyAndChannelSinks(..., out envoySink, out channelSink);
        RemotingServices.SetEnvoyAndChannelSinks(identity, envoySink, channelSink);
    }
    // 呼叫 CallProcessMessage(identity.ChannelSink, req, ...) 其中 ChannelSink 型別為 IMessageSink
}

關鍵發現

  • CallProcessMessage 參數為 IMessageSink,故插入 ChannelSink 鏈首的 MessageSink 會被正確呼叫 SyncProcessMessage。
  • 自訂 MessageSink 必須插在 FormatterSink 之前 (組態檔 `` 中置於 `` 前);伺服器端則相反。

總結

透過實作 IClientChannelSinkProvider 並偽裝成 IClientChannelSink,可將自訂 MessageSink 注入客戶端 Pipeline 格式化器前,實現訊息層級攔截與修改。下篇將探討同一 AppDomain 內跨 Context 呼叫的攔截機制 (涉及更多 Sink 類型)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved