利用消息机制实现.NET AOP(面向方面编程)--利用RealProxy和消息接收器实现多截获...

本文介绍了一种使用.NET Remoting中的RealProxy类实现面向方面编程(AOP)的方法。通过创建自定义的消息处理链,可以在不修改原始业务逻辑的情况下添加横切关注点,如日志记录等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

以下代码实现利用RealProxy调用MessageSink链来实现多截获

// TerminatorSink.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;


namespace  DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
public class TerminatorSink:IMessageSink
    
{
        
public delegate IMessage MessageTerminatorDelegate(IMessage msg);

        
private MarshalByRefObject _target;
        
private MessageTerminatorDelegate _delegate;

        
public TerminatorSink(MarshalByRefObject target,MessageTerminatorDelegate d)
        
{
            _target 
= target;
            _delegate 
= d;
        }


        
IMessageSink 成员#region IMessageSink 成员

        
public IMessage SyncProcessMessage(IMessage msg)
        
{

            
if (_delegate == null)
                
return new ReturnMessage(new Exception("没有处理消息的委拖"), (IMethodCallMessage)msg);
            
else
                
return _delegate(msg);
        }


        
public IMessageSink NextSink
        
{
            
get
            
{
                
return null ;
            }

        }


        
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        
{
            
throw new NotImplementedException("TerminatorSink 不支持异步处理消息");
        }


        
#endregion

    }

}


// ObjectWithAspect.cs
using  System;

namespace  DotNetAOP.MessageSinkWithRealProxy.Framework
{
    [AOPProxy]
    
public abstract class ObjectWithAspects:ContextBoundObject
    
{
    }

}


// MessageChainProxy.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;

namespace  DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
public class MessageChainProxy: RealProxy
    
{
        
private MarshalByRefObject _target;
        
private Type _type;

        
public MessageChainProxy(Type type,MarshalByRefObject target): base(type)
        
{
            _target 
= target;
            _type 
= type;
        }


        
public override IMessage Invoke(IMessage msg)
        
{

            IMessageSink sink 
= new TerminatorSink(_target,new TerminatorSink.MessageTerminatorDelegate(ProcessMessage));
            AspectAttribute[] sinks 
= GetAspectAttributes(_type);
            
forint i = sinks.Length - 1; i >= 0 ; i -- )
            
{
                AspectAttribute aspectAttribute 
= sinks[i];
                sink 
= aspectAttribute.CreateAspectSink(sink);
            }

            
return sink.SyncProcessMessage(msg);
        }


        
private AspectAttribute[] GetAspectAttributes(Type type)
        
{
            
return (AspectAttribute[])_type.GetCustomAttributes(typeof(AspectAttribute), true);
        }


        
private IMessage ProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;

            IMethodReturnMessage back 
= null;
            
if (ctr != null)
            
{
                RealProxy defaultProxy 
= RemotingServices.GetRealProxy(_target);
                defaultProxy.InitializeServerObject(ctr);

                back 
= EnterpriseServicesHelper.CreateConstructionReturnMessage
                    (ctr, (MarshalByRefObject)GetTransparentProxy());
            }

            
else
            
{
                back 
= RemotingServices.ExecuteMessage(_target, call);
            }

            
return back;
        }


    }

}


// AsyncReplyHelperSink.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;


namespace  DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
class AsyncReplyHelperSink : IMessageSink
    
{
        
public delegate IMessage AsyncReplyHelperSinkDelegate(IMessage msg);

        IMessageSink _nextSink 
= null;
        AsyncReplyHelperSinkDelegate _delegate 
= null;

        
public AsyncReplyHelperSink(IMessageSink nextSink, AsyncReplyHelperSinkDelegate delegates)
        
{
            _nextSink 
= nextSink;
            _delegate 
= delegates;
        }


        
IMessageSink 成员#region IMessageSink 成员

        
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        
{
            
return null;
        }


        
public IMessageSink NextSink
        
{
            
get return _nextSink; }
        }


        
public IMessage SyncProcessMessage(IMessage msg)
        
{
            
if (_delegate == null)
            
{
                
return new ReturnMessage(new Exception("没有处理消息委拖"), (IMethodCallMessage)msg);
            }

            
else
            
{
                IMessage back 
= _delegate(msg);
                
return _nextSink.SyncProcessMessage(back);
            }

        }


        
#endregion

    }

}


// AspectAttribute.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;

namespace  DotNetAOP.MessageSinkWithRealProxy.Framework
{
    
public abstract class AspectAttribute:Attribute
    
{
        
public abstract IMessageSink CreateAspectSink(IMessageSink nextSink);
    }

}

 

// AopProxyAttribute.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;

namespace  DotNetAOP.MessageSinkWithRealProxy.Framework
{
    [AttributeUsage(AttributeTargets.Class)]
    
public class AOPProxyAttribute:ProxyAttribute
    
{


        
public override MarshalByRefObject CreateInstance(Type serverType)
        
{
            MarshalByRefObject rawInstance 
=  base.CreateInstance (serverType);
            RealProxy rp 
= new MessageChainProxy(serverType, rawInstance);
            
return (MarshalByRefObject)rp.GetTransparentProxy();
        }


    }

}

 

// 以上为框架代码
// 以下为Demo代码

// Calculator.cs
using  System;

using  DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace  DotNetAOP.MessageSinkWithRealProxy.Demo
{
    [LogSink,Log2Sink]
    
public class Calculator:ObjectWithAspects
    
{
        
public Calculator()
        
{
        }

        
public double Add(double a , double b)
        
{
            
return a + b;
        }

        
public double Divide(double a, double b)
        
{
            
return a/b;
        }

    }

}


// Log2Sink.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;

using  DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace  DotNetAOP.MessageSinkWithRealProxy.Demo
{
    
public class Log2Sink : IMessageSink
    
{
        
readonly IMessageSink _nextSink;
        
public Log2Sink(IMessageSink nextSink)
        
{
            _nextSink 
= nextSink;
        }

        
IMessageSink 成员#region IMessageSink 成员

        
public IMessage SyncProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;

            IMethodReturnMessage back 
= null;

            Console.WriteLine(
"第二个处理器");

            back 
= (IMethodReturnMessage)NextSink.SyncProcessMessage(msg);
            
            
return back;
        }


        
public IMessageSink NextSink
        
{
            
get
            
{
                
return _nextSink;
            }

        }


        
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        
{
            AsyncReplyHelperSink.AsyncReplyHelperSinkDelegate asd 
= new AsyncReplyHelperSink.AsyncReplyHelperSinkDelegate(AsyncProcessMessage);

            replySink 
= new AsyncReplyHelperSink(replySink, asd);

            
if (_nextSink != null)
            
{
                
return _nextSink.AsyncProcessMessage(msg, replySink);
            }

            
else
            
{
                
return null;
            }

        }


        
#endregion


        
private IMessage AsyncProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;
            
if (ctr != null)
            
{
                Console.WriteLine(
"构造函数:\t" + ctr.MethodName);
            }

            
else
            
{
                Console.WriteLine(
"普通方法:\t" + call.MethodName);
            }

            
return msg;

        }

    }



    [AttributeUsage(AttributeTargets.Class)]
    
public class Log2SinkAttribute : AspectAttribute
    
{
        
public override IMessageSink CreateAspectSink(IMessageSink nextSink)
        
{
            
return new Log2Sink(nextSink);
        }


    }

}


// LOgSink.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;

using  DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace  DotNetAOP.MessageSinkWithRealProxy.Demo
{
    
public class Log2Sink : IMessageSink
    
{
        
readonly IMessageSink _nextSink;
        
public Log2Sink(IMessageSink nextSink)
        
{
            _nextSink 
= nextSink;
        }

        
IMessageSink 成员#region IMessageSink 成员

        
public IMessage SyncProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;

            IMethodReturnMessage back 
= null;

            Console.WriteLine(
"第二个处理器");

            back 
= (IMethodReturnMessage)NextSink.SyncProcessMessage(msg);
            
            
return back;
        }


        
public IMessageSink NextSink
        
{
            
get
            
{
                
return _nextSink;
            }

        }


        
public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        
{
            AsyncReplyHelperSink.AsyncReplyHelperSinkDelegate asd 
= new AsyncReplyHelperSink.AsyncReplyHelperSinkDelegate(AsyncProcessMessage);

            replySink 
= new AsyncReplyHelperSink(replySink, asd);

            
if (_nextSink != null)
            
{
                
return _nextSink.AsyncProcessMessage(msg, replySink);
            }

            
else
            
{
                
return null;
            }

        }


        
#endregion

        
private IMessage AsyncProcessMessage(IMessage msg)
        
{
            IMethodCallMessage call 
= msg as IMethodCallMessage;
            IConstructionCallMessage ctr 
= call as IConstructionCallMessage;
            
if (ctr != null)
            
{
                Console.WriteLine(
"构造函数:\t" + ctr.MethodName);
            }

            
else
            
{
                Console.WriteLine(
"普通方法:\t" + call.MethodName);
            }

            
return msg;

        }

    }



    [AttributeUsage(AttributeTargets.Class)]
    
public class Log2SinkAttribute : AspectAttribute
    
{
        
public override IMessageSink CreateAspectSink(IMessageSink nextSink)
        
{
            
return new Log2Sink(nextSink);
        }


    }

}


// LogSinkAttribute.cs
using  System;
using  System.Runtime.Remoting;
using  System.Runtime.Remoting.Activation;
using  System.Runtime.Remoting.Contexts;
using  System.Runtime.Remoting.Messaging;
using  System.Runtime.Remoting.Proxies;
using  System.Runtime.Remoting.Services;

using  DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace  DotNetAOP.MessageSinkWithRealProxy.Demo
{
    [AttributeUsage(AttributeTargets.Class)]
    
public class LogSinkAttribute:AspectAttribute
    
{
        
public override IMessageSink CreateAspectSink(IMessageSink nextSink)
        
{
            
return new LogSink(nextSink);
        }


    }

}


// Program.cs
using  System;

using  DotNetAOP.MessageSinkWithRealProxy.Framework;

namespace  DotNetAOP.MessageSinkWithRealProxy.Demo
{
    
/**//// <summary>
    
/// Class1 的摘要说明。
    
/// </summary>

    class Program
    
{
        
/**//// <summary>
        
/// 应用程序的主入口点。
        
/// </summary>

        [STAThread]
        
static void Main(string[] args)
        
{
            Calculator calc 
= new Calculator();
            Console.WriteLine(calc.Add(
1,2));
            Console.WriteLine(calc.Divide(
2,0));
//            Test2 t2 = new Test2();
//            t2.Te();
            Console.ReadLine();
        }

    }

}

 

需要上面完整代码请留下Email。
年久,源代码已失,不能提供,请见谅
查看其它框架实现请转到此页

利用消息机制实现.NET AOP(面向方面编程)--通过RealProxy实现
利用消息机制实现.NET AOP(面向方面编程)--利用RealProxy和消息接收器实现多截获
利用消息机制实现.NET AOP(面向方面编程)--利用ServerContextSink实现多截获

转载于:https://www.cnblogs.com/think/archive/2006/07/26/460376.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值