采用AOP 的观点来 Log 所有方法的调用

微软中文和英文分别有两篇介绍

http://www.microsoft.com/china/MSDN/library/windev/COMponentdev/AspectOrientedProgrammingEnablesBetterCodeEncapsulationandReuse.mspx?pf=true

http://msdn.microsoft.com/msdnmag/issues/03/03/ContextsinNET/default.aspx



AOP 的观点,在 Dotnet 中显的更容易实现。我写了一个简单的来自,来log 对 Person 的所有调用

假设有这个的一个实体类。

< Log () >  _ 
 
Public   Class Person 
    
Inherits ContextBoundObject 
 
    
Sub New(ByVal s As String
 
    
End Sub
 
 
    
Public Function SayHello(ByVal yourName As StringAs String 
        
Return "Hello: " + yourName 
    
End Function
 
End Class
 


这里的对象跟普通的对象有一点不同:
1. 加上了一个从 CustomeAttribute 集成过来的属性
2. 从ContextBoundObject

后面就要实现这样的一个属性,这个属性主要是为对象的上下文环境中添加自己的属性,在属性中嵌入自己的sink

属性的写法:

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

Public   Class LogAttribute
    
Inherits ContextAttribute
    
Sub New()
        
MyBase.New("LogAttribute")
    
End Sub

    
Public Overrides Sub GetPropertiesForNewContext(ByVal ctorMsg As System.Runtime.Remoting.Activation.IConstructionCallMessage)

        
' 添加一个新的属性到上下文的属性中

        
Dim myContextLogProperty As New ContextLogProperty
        ctorMsg.ContextProperties.Add(myContextLogProperty)

    
End Sub


    
Public Overrides Function IsContextOK(ByVal ctx As System.Runtime.Remoting.Contexts.Context, ByVal ctorMsg As System.Runtime.Remoting.Activation.IConstructionCallMessage) As Boolean
        
Return False
        
' false 表示还有新的属性要加进去
    End Function


End Class



然后就是property 和 SInk

Public   Class ContextLogProperty
    
Implements IContextProperty, IContributeServerContextSink
    
Public Sub Freeze(ByVal newContext As System.Runtime.Remoting.Contexts.Context) Implements System.Runtime.Remoting.Contexts.IContextProperty.Freeze

    
End Sub


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


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


    
Public Function GetServerContextSink(ByVal nextSink As IMessageSink) As IMessageSink Implements System.Runtime.Remoting.Contexts.IContributeServerContextSink.GetServerContextSink
        
Dim sink As New LogSink(nextSink)
        
Return sink
    
End Function


End Class



Public   Class LogSink
    
Implements IMessageSink
    
Private _nextSink As IMessageSink
    
Sub New(ByVal nextSink As IMessageSink)
        _nextSink 
= nextSink
    
End Sub

    
Public Function AsyncProcessMessage(ByVal msg As IMessage, ByVal replySink As IMessageSink) As IMessageCtrl Implements IMessageSink.AsyncProcessMessage
        
'Debug.Assert(False)
        Return _nextSink.AsyncProcessMessage(msg, replySink)
    
End Function


    
Public ReadOnly Property NextSink() As IMessageSink Implements IMessageSink.NextSink
        
Get
            
Return _nextSink
        
End Get
    
End Property


    
Public Function SyncProcessMessage(ByVal msg As IMessage) As IMessage Implements IMessageSink.SyncProcessMessage
        LogMessage(msg)
        
Return _nextSink.SyncProcessMessage(msg)
    
End Function


    
Public Sub LogMessage(ByVal msg As IMessage)
        
If TypeOf (msg) Is IConstructionCallMessage Then
            MessageBox.Show(
String.Format("{0}的构造函数"CType(msg, IConstructionCallMessage).TypeName))
        
End If
        
If TypeOf (msg) Is IMethodMessage Then
            
Dim msg1 As IMethodMessage = CType(msg, IMethodMessage)
            MessageBox.Show(
String.Format("方法{0}参数个数{1}", msg1.MethodName, msg1.ArgCount))
        
End If
    
End Sub

End Class

然后调用person 的方法的时候,你会发现自定义sink 会按照 ImessageSink 的模型可以对流经该 sinnk 的msn 做自己的log 或者其他处理。

你可能感兴趣的:(AOP)