ContextBoundObject:MethodWatcher

Author:水如烟

有关见异类HOW TO:适时弹出指示框(汇总) .
现在重列基类代码,是因为作了一些改动.在下文中,将继承这些类作一个示例:代码如社会般,暗处有玄机。所以,NET说ContextBoundObject是不用用户使用的,是有道理的。代码本身不作说明,因为自己也不懂。

MethodWatcherAppendBaseAttribute.vb

Namespace  uRemoting.MethodWatcher

    
< AttributeUsage(AttributeTargets.Class, allowmultiple: = True ) >  _
    
Public   MustInherit   Class  MethodWatcherAppendBaseAttribute
        
Inherits  Attribute

        
Private  gMethodName  As   String
        
Private  gWatchContextType  As  System.Type

        
Sub   New ()

        
End Sub

        
Sub   New ( ByVal  methodName  As   String )
            gMethodName 
=  methodName
        
End Sub

        
Public   Property  MethodName()  As   String
            
Get
                
Return  gMethodName
            
End   Get
            
Set ( ByVal  value  As   String )
                gMethodName 
=  value
            
End   Set
        
End Property

        
Public   Sub  SetContextType( ByVal  contextType  As  System.Type)
            gWatchContextType 
=  contextType
        
End Sub

        
Public   ReadOnly   Property  FullMethodName()  As   String
            
Get
                
Return  MethodWatcherCommon.GetFullMethodName(gWatchContextType, MethodName,  Me .GetType)
            
End   Get
        
End Property
    
End Class


End Namespace


MethodWatcherBaseAttribute.vb

Imports  System.Runtime.Remoting.Contexts
Imports  System.Runtime.Remoting.Activation

Namespace  uRemoting.MethodWatcher

    
< AttributeUsage(AttributeTargets.Class) >  _
    
Public   MustInherit   Class  MethodWatcherBaseAttribute
        
Inherits  ContextAttribute

        
Sub   New ()
            
MyBase .New( " MethodWatcherBase " )
        
End Sub

        
Public   Overrides   Sub  GetPropertiesForNewContext( ByVal  ctorMsg  As  System.Runtime.Remoting.Activation.IConstructionCallMessage)
            MethodCollection.GetAppendMethodsFromType(ctorMsg.ActivationType) 
' 从ctorMsg中取类要绑定的方法信息
            ctorMsg.ContextProperties.Add(GetMethodWatcherProperty)
        
End Sub

        
Protected   MustOverride   Function  GetMethodWatcherProperty()  As  MethodWatcherBaseProperty

    
End Class

End Namespace


MethodWatcherBaseProperty.vb

Imports  System.Runtime.Remoting.Activation
Imports  System.Runtime.Remoting.Contexts
Imports  System.Runtime.Remoting.Messaging

Namespace  uRemoting.MethodWatcher

    
Public   MustInherit   Class  MethodWatcherBaseProperty
        
Implements  IContextProperty, IContributeObjectSink

        
Protected   MustOverride   Function  CreateSink( ByVal  nextSink  As  IMessageSink)  As  IMessageSink

        
Protected   Overridable   Function  GetName()  As   String
            
Return   Me .GetType.Name   ' "MethodWatcherBase"
         End Function

        
Protected   Overridable   Sub  FreezeImpl( ByVal  newContext  As  Context)
            
Return
        
End Sub

        
Protected   Overridable   Function  CheckNewContext( ByVal  newCtx  As  Context)  As   Boolean
            
Return   True
        
End Function


        
Public   Sub  Freeze( ByVal  newContext  As  System.Runtime.Remoting.Contexts.Context)  Implements  System.Runtime.Remoting.Contexts.IContextProperty.Freeze
            FreezeImpl(newContext)
        
End Sub

        
Public   Function  IsNewContextOK( ByVal  newCtx  As  System.Runtime.Remoting.Contexts.Context)  As   Boolean   Implements  System.Runtime.Remoting.Contexts.IContextProperty.IsNewContextOK
            
Return  CheckNewContext(newCtx)
        
End Function

        
Public   ReadOnly   Property  Name()  As   String   Implements  System.Runtime.Remoting.Contexts.IContextProperty.Name
            
Get
                
Return  GetName()
            
End   Get
        
End Property

        
Public   Function  GetObjectSink( ByVal  obj  As  System.MarshalByRefObject,  ByVal  nextSink  As  System.Runtime.Remoting.Messaging.IMessageSink)  As  System.Runtime.Remoting.Messaging.IMessageSink  Implements  System.Runtime.Remoting.Contexts.IContributeObjectSink.GetObjectSink
            
Return  CreateSink(nextSink)
        
End Function

    
End Class

End Namespace


MethodWatcherBaseSink.vb

Imports  System.Collections
Imports  System.Runtime.Remoting.Contexts
Imports  System.Runtime.Remoting.Messaging
Imports  System.Runtime.Remoting.Activation

Namespace  uRemoting.MethodWatcher

    
Public   MustInherit   Class  MethodWatcherBaseSink
        
Implements  IMessageSink

        
Private  m_BeforeHandles  As  SortedList
        
Private  m_AfterHandles  As  SortedList
        
Private  m_NextSink  As  IMessageSink

        
Sub   New ( ByVal  nextSink  As  IMessageSink)
            m_NextSink 
=  nextSink
            m_BeforeHandles 
=   New  SortedList
            m_AfterHandles 
=   New  SortedList
            AddAllBeforeMethodCallHandles()
            AddAllAfterMethodCallHandles()
        
End Sub

        
Protected   Sub  AddBeforeMethodCallHandle( ByVal  methodName  As   String ByVal  beforeHandle  As  BeforeMethodCallHandle)
            
SyncLock   Me .m_BeforeHandles
                
If   Not   Me .m_BeforeHandles.Contains(methodName)  Then
                    m_BeforeHandles.Add(methodName, beforeHandle)
                
End   If
            
End   SyncLock
        
End Sub

        
Protected   Sub  AddAfterMethodCallHandle( ByVal  methodName  As   String ByVal  afterHandle  As  AfterMethodCallHandle)
            
SyncLock   Me .m_AfterHandles
                
If   Not   Me .m_AfterHandles.Contains(methodName)  Then
                    m_AfterHandles.Add(methodName, afterHandle)
                
End   If
            
End   SyncLock
        
End Sub

        
Protected   Sub  AddAllBeforeMethodCallHandles()
            
For   Each  methodName  As   String   In  MethodCollection.DefaultInstance.Keys
                
If  MethodCollection.DefaultInstance(methodName).GetType.Equals(MethodWatcherAppendAttributeType)  Then
                    AddBeforeMethodCallHandle(methodName, 
New  BeforeMethodCallHandle( AddressOf  Before_MethodCall))
                
End   If
            
Next
        
End Sub

        
Protected   Sub  AddAllAfterMethodCallHandles()
            
For   Each  methodName  As   String   In  MethodCollection.DefaultInstance.Keys
                
If  MethodCollection.DefaultInstance(methodName).GetType.Equals(MethodWatcherAppendAttributeType)  Then
                    AddAfterMethodCallHandle(methodName, 
New  AfterMethodCallHandle( AddressOf  After_MethodCall))
                
End   If
            
Next
        
End Sub


        
Protected   Overridable   Sub  Before_MethodCall( ByVal  callMsg  As  IMethodCallMessage,  ByVal  MethodAppendType  As  System.Type)
            
If  callMsg  Is   Nothing   Then
                
Return
            
End   If

            MethodWatcherCenter.ReceiveBeforeMethodCallEvent(callMsg, MethodAppendType)
        
End Sub

        
Protected   Overridable   Sub  After_MethodCall( ByVal  replyMsg  As  IMethodReturnMessage,  ByVal  MethodAppendType  As  System.Type)
            
If  replyMsg  Is   Nothing   Then
                
Return
            
End   If

            MethodWatcherCenter.ReceiveAfterMethodCallEvent(replyMsg, MethodAppendType)
        
End Sub

        
Protected   MustOverride   ReadOnly   Property  MethodWatcherAppendAttributeType()  As  Type

        
Protected   Function  FindBeforeMethodCallHandle( ByVal  methodName  As   String As  BeforeMethodCallHandle
            
Dim  beforeHandle  As  BeforeMethodCallHandle
            
SyncLock   Me .m_BeforeHandles
                beforeHandle 
=   CType (m_BeforeHandles(methodName), BeforeMethodCallHandle)
            
End   SyncLock
            
Return  beforeHandle
        
End Function

        
Protected   Function  FindAfterMethodCallHandle( ByVal  methodName  As   String As  AfterMethodCallHandle
            
Dim  afterHandle  As  AfterMethodCallHandle
            
SyncLock   Me .m_AfterHandles
                afterHandle 
=   CType (m_AfterHandles(methodName), AfterMethodCallHandle)
            
End   SyncLock
            
Return  afterHandle
        
End Function

        
Public   Function  AsyncProcessMessage( ByVal  msg  As  System.Runtime.Remoting.Messaging.IMessage,  ByVal  replySink  As  System.Runtime.Remoting.Messaging.IMessageSink)  As  System.Runtime.Remoting.Messaging.IMessageCtrl  Implements  System.Runtime.Remoting.Messaging.IMessageSink.AsyncProcessMessage
            
Return   Nothing
        
End Function

        
Public   ReadOnly   Property  NextSink()  As  System.Runtime.Remoting.Messaging.IMessageSink  Implements  System.Runtime.Remoting.Messaging.IMessageSink.NextSink
            
Get
                
Return  m_NextSink
            
End   Get
        
End Property


        
Public   Function  SyncProcessMessage( ByVal  msg  As  System.Runtime.Remoting.Messaging.IMessage)  As  System.Runtime.Remoting.Messaging.IMessage  Implements  System.Runtime.Remoting.Messaging.IMessageSink.SyncProcessMessage
            
Dim  [ call As  IMethodCallMessage  =   CType (msg, IMethodCallMessage)
            
Dim  methodName  As   String   =  MethodWatcherCommon.GetFullMethodName(msg, MethodWatcherAppendAttributeType)  ' 这里取全名
             Dim  beforeHandle  As  BeforeMethodCallHandle  =  FindBeforeMethodCallHandle(methodName)

            
If  beforeHandle IsNot  Nothing   Then
                beforeHandle([
call ], MethodWatcherAppendAttributeType)
            
End   If

            
Dim  retMsg  As  System.Runtime.Remoting.Messaging.IMessage  =  m_NextSink.SyncProcessMessage(msg)
            
Dim  reply  As  IMethodReturnMessage  =   CType (retMsg, IMethodReturnMessage)
            
Dim  afterHandle  As  AfterMethodCallHandle  =  FindAfterMethodCallHandle(methodName)

            
If  afterHandle IsNot  Nothing   Then
                afterHandle(reply, MethodWatcherAppendAttributeType)
            
End   If

            
Return  retMsg
        
End Function
    
End Class

End Namespace


MethodWatcherDelegate.vb

Imports  System.Runtime.Remoting.Messaging

Namespace  uRemoting.MethodWatcher

    
Public   Delegate   Sub  BeforeMethodCallHandle( ByVal  callMsg  As  IMethodCallMessage,  ByVal  MethodAppendType  As  System.Type)
    
Public   Delegate   Sub  AfterMethodCallHandle( ByVal  replyMsg  As  IMethodReturnMessage,  ByVal  MethodAppendType  As  System.Type)

End Namespace


MethodCollection.vb

Namespace  uRemoting.MethodWatcher

    
Friend   Class  MethodCollection
        
Inherits  Dictionary(Of  String , MethodWatcherAppendBaseAttribute)

        
Private   Shared  gCollection  As  MethodCollection
        
Shared   Sub   New ()
            gCollection 
=   New  MethodCollection
            gContextBoundObjctMethods 
=   New  Dictionary(Of  String Object )

            
For   Each  m  As  Reflection.MethodInfo  In   GetType (ContextBoundObject).GetMethods
                gContextBoundObjctMethods.Add(m.Name, 
Nothing )
            
Next
        
End Sub
        
Private   Sub   New ()
        
End Sub

        
Public   Shared   ReadOnly   Property  DefaultInstance()  As  MethodCollection
            
Get
                
Return  gCollection
            
End   Get
        
End Property

        
Public   Shared   Sub  GetAppendMethodsFromType( ByVal  contextType  As  Type)

            
For   Each  tmpCustomAttribute  As   Object   In  contextType.GetCustomAttributes( True )
                
If  tmpCustomAttribute.GetType.BaseType  Is   GetType (MethodWatcherAppendBaseAttribute)  Then

                    
Dim  tmpAppendAttribute  As  MethodWatcherAppendBaseAttribute  =   CType (tmpCustomAttribute, MethodWatcherAppendBaseAttribute)
                    tmpAppendAttribute.SetContextType(contextType)

                    
If  tmpAppendAttribute.MethodName  =   ""   Then
                        
For   Each  m  As  Reflection.MemberInfo  In  contextType.GetMethods
                            
If   Not  gContextBoundObjctMethods.ContainsKey(m.Name)  Then
                                tmpAppendAttribute.MethodName 
=  m.Name
                                AddMethod(tmpAppendAttribute)
                            
End   If
                        
Next
                    
Else
                        AddMethod(tmpAppendAttribute)
                    
End   If

                
End   If
            
Next
        
End Sub

        
Private   Shared   Sub  AddMethod( ByVal  methodAppendAttibute  As  MethodWatcherAppendBaseAttribute)
            
SyncLock  gCollection
                
If   Not  DefaultInstance.ContainsKey(methodAppendAttibute.FullMethodName)  Then
                    DefaultInstance.Add(methodAppendAttibute.FullMethodName, methodAppendAttibute)
                
End   If
            
End   SyncLock
        
End Sub

        
Private   Shared  gContextBoundObjctMethods  As  Dictionary(Of  String Object )

    
End Class

End Namespace


MethodWatcherCenter.vb

Imports  System.Runtime.Remoting.Messaging

Namespace  uRemoting.MethodWatcher

    
Public   Class  MethodWatcherCenter

        
Public   Shared   Event  MethodCallBegin  As  BeforeMethodCallHandle
        
Public   Shared   Event  MethodCallOver  As  AfterMethodCallHandle

        
Friend   Shared   Sub  ReceiveBeforeMethodCallEvent( ByVal  callMsg  As  IMethodCallMessage,  ByVal  MethodAppendType  As  System.Type)
            
RaiseEvent  MethodCallBegin(callMsg, MethodAppendType)
        
End Sub

        
Friend   Shared   Sub  ReceiveAfterMethodCallEvent( ByVal  replyMsg  As  IMethodReturnMessage,  ByVal  MethodAppendType  As  System.Type)
            
RaiseEvent  MethodCallOver(replyMsg, MethodAppendType)
        
End Sub

    
End Class

End Namespace


MethodWatcherCommon.vb

Namespace  uRemoting.MethodWatcher

    
Friend   Class  MethodWatcherCommon
        
Private   Sub   New ()
        
End Sub

        
Public   Shared   Function  GetFullMethodName( ByVal  contextType  As  System.Type,  ByVal  methodName  As   String ByVal  MeathodAppendAttibuteType  As  System.Type)  As   String
            
Return   String .Format( " {0}+{1}:{2} " , contextType.FullName, methodName, MeathodAppendAttibuteType.Name)
        
End Function

        
Public   Shared   Function  GetFullMethodName( ByVal  msg  As  System.Runtime.Remoting.Messaging.IMessage,  ByVal  MethodAppendType  As  System.Type)  As   String
            
Dim  tmpType  As  Type  =  Type.GetType(msg.Properties( " __TypeName " ).ToString)
            
Dim  tmpMethodName  As   String   =  msg.Properties( " __MethodName " ).ToString
            
Return  GetFullMethodName(tmpType, tmpMethodName, MethodAppendType)
        
End Function

        
Public   Shared   Function  GetFullMethodName( ByVal  callMsg  As  System.Runtime.Remoting.Messaging.IMethodCallMessage,  ByVal  MethodAppendType  As  System.Type)  As   String
            
Return  GetFullMethodName( CType (callMsg, System.Runtime.Remoting.Messaging.IMessage), MethodAppendType)
        
End Function

        
Public   Shared   Function  GetFullMethodName( ByVal  replyMsg  As  System.Runtime.Remoting.Messaging.IMethodReturnMessage,  ByVal  MethodAppendType  As  System.Type)  As   String
            
Return  GetFullMethodName( CType (replyMsg, System.Runtime.Remoting.Messaging.IMessage), MethodAppendType)
        
End Function

    
End Class

End Namespace


 一个简单的Watcher:SimpleMethodWatcher
SimpleMethodWatcherAppendAttribute.vb

Namespace  uRemoting.MethodWatcher
    
< AttributeUsage(AttributeTargets.Class, allowmultiple: = True ) >  _
    
Public   NotInheritable   Class  SimpleMethodWatcherAppendAttribute
        
Inherits  MethodWatcherAppendBaseAttribute

        
Sub   New ()
        
End Sub

        
Sub   New ( ByVal  methodName  As   String )
            
MyBase .New(methodName)
        
End Sub

    
End Class

End Namespace


SimpleMethodWatcherAttribute.vb

Namespace  uRemoting.MethodWatcher
    
< AttributeUsage(AttributeTargets.Class) >  _
    
Public   Class  SimpleMethodWatcherAttribute
        
Inherits  MethodWatcherBaseAttribute

        
Protected   Overrides   Function  GetMethodWatcherProperty()  As  MethodWatcherBaseProperty
            
Return   New  SimpleMethodWatcherProperty
        
End Function
    
End Class

End Namespace


SimpleMethodWatcherCenter.vb

Imports  System.Runtime.Remoting.Messaging

Namespace  uRemoting.MethodWatcher

    
Public   Class  SimpleMethodWatcherCenter
        
Inherits  MethodWatcherCenter

        
Public   Sub  Ready()
            Remove()
            
AddHandler  MethodCallBegin,  New  BeforeMethodCallHandle( AddressOf  WriteMethodCallBegin)
            
AddHandler  MethodCallOver,  New  AfterMethodCallHandle( AddressOf  WriteMethodCallOver)
        
End Sub

        
Public   Sub  Remove()
            
RemoveHandler  MethodCallBegin,  New  BeforeMethodCallHandle( AddressOf  WriteMethodCallBegin)
            
RemoveHandler  MethodCallOver,  New  AfterMethodCallHandle( AddressOf  WriteMethodCallOver)
        
End Sub

        
Protected   Overridable   Sub  WriteMethodCallBegin( ByVal  callMsg  As  IMethodCallMessage,  ByVal  MethodAppendType  As  System.Type)
            
If  MethodAppendType.Equals( GetType (SimpleMethodWatcherAppendAttribute))  Then

            
Else

            
End   If
        
End Sub

        
Protected   Overridable   Sub  WriteMethodCallOver( ByVal  replyMsg  As  IMethodReturnMessage,  ByVal  MethodAppendType  As  System.Type)
            
If  MethodAppendType.Equals( GetType (SimpleMethodWatcherAppendAttribute))  Then

            
Else

            
End   If
        
End Sub

    
End Class

End Namespace


SimpleMethodWatcherProperty.vb

Namespace  uRemoting.MethodWatcher

    
Public   Class  SimpleMethodWatcherProperty
        
Inherits  MethodWatcherBaseProperty

        
Protected   Overrides   Function  CreateSink( ByVal  nextSink  As  System.Runtime.Remoting.Messaging.IMessageSink)  As  System.Runtime.Remoting.Messaging.IMessageSink
            
Return   New  SimpleMethodWatcherSink(nextSink)
        
End Function

    
End Class

End Namespace


SimpleMethodWatcherSink.vb

Imports  System.Runtime.Remoting.Messaging

Namespace  uRemoting.MethodWatcher

    
Public   Class  SimpleMethodWatcherSink
        
Inherits  MethodWatcherBaseSink

        
Sub   New ( ByVal  nextSink  As  IMessageSink)
            
MyBase .New(nextSink)
        
End Sub

        
Protected   Overrides   ReadOnly   Property  MethodWatcherAppendAttributeType()  As  System.Type
            
Get
                
Return   GetType (SimpleMethodWatcherAppendAttribute)
            
End   Get
        
End Property
    
End Class

End Namespace
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值