using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Remoting.Messaging;
using System.Runtime.Remoting.Activation;
using System.Runtime.Remoting;
using NewAop;
using System.Runtime.Remoting.Proxies;
using System.Runtime.Remoting.Services;
using System.ServiceModel;
using System.Runtime.Serialization; namespace NewAop
{ /// <summary>
/// IAopOperator AOP操作符接口,包括前处理和后处理
/// </summary>
public interface IAopOperator
{
void PreProcess(IMessage requestMsg);
void PostProcess(IMessage requestMsg, IMessage Respond);
}
/// <summary>
/// MethodAopSwitcherAttribute 用于决定一个被AopProxyAttribute修饰的class的某个特定方法是否启用截获 。
/// 创建原因:绝大多数时候我们只希望对某个类的一部分Method而不是所有Method使用截获。
/// 使用方法:如果一个方法没有使用MethodAopSwitcherAttribute特性或使用MethodAopSwitcherAttribute(false)修饰,
/// 都不会对其进行截获。只对使用了MethodAopSwitcherAttribute(true)启用截获。
/// </summary>
[AttributeUsage(AttributeTargets.Method, AllowMultiple = true,Inherited =true)]
public class MethodAopSwitcherAttribute : Attribute
{
private int useAspect = ; //记录类型
private string userlog = ""; //记录详细信息
public MethodAopSwitcherAttribute(int useAop=, string log="")
{
this.useAspect = useAop;
this.userlog = log;
} public int UseAspect
{
get
{
return this.useAspect;
}
}
public string Userlog
{
get
{
return this.userlog;
}
}
}
/// <summary>
/// IAopProxyFactory 用于创建特定的Aop代理的实例,IAopProxyFactory的作用是使AopProxyAttribute独立于具体的AOP代理类。
/// </summary>
public interface IAopProxyFactory
{
AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type);
}
/// <summary>
/// AopProxyBase 抽象类 所有自定义AOP代理类都从此类派生,覆写IAopOperator接口,实现具体的前/后处理 。
/// </summary>
public abstract class AopProxyBase : RealProxy, IAopOperator
{
public readonly MarshalByRefObject target; //默认透明代理 #region IAopOperator 成员(两个方法 一个在执行之前调用,另一个在执行之后调用,具体实现代码写在AopControlProxy类中)
public abstract void PreProcess(IMessage requestMsg); //方法执行的预处理逻辑
public abstract void PostProcess(IMessage requestMsg, IMessage Respond); //方法执行结束的处理逻辑
#endregion public AopProxyBase(MarshalByRefObject obj, Type type)
: base(type)
{
this.target = obj;
} #region Invoke 重写基方法
public abstract override IMessage Invoke(IMessage msg); #endregion
}
/// <summary>
/// AopProxyAttribute
/// AOP代理特性,如果一个类想实现具体的AOP,只要实现AopProxyBase和IAopProxyFactory,然后加上该特性即可。
/// </summary> [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)]
public class AopProxyAttribute : ProxyAttribute
{
private IAopProxyFactory proxyFactory = null; public AopProxyAttribute(Type factoryType)
{
this.proxyFactory = (IAopProxyFactory)Activator.CreateInstance(factoryType);
} #region 创建实例
/// <summary>
/// 获得目标对象的自定义透明代理
/// </summary>
public override MarshalByRefObject CreateInstance(Type serverType)//serverType是被AopProxyAttribute修饰的类
{
//未初始化的实例的默认透明代理
MarshalByRefObject target = base.CreateInstance(serverType); //得到位初始化的实例(ctor未执行)
object[] args = { target, serverType };
//AopProxyBase rp = (AopProxyBase)Activator.CreateInstance(this.realProxyType ,args) ; //Activator.CreateInstance在调用ctor时通过了代理,所以此处将会失败 //得到自定义的真实代理
AopProxyBase rp = this.proxyFactory.CreateAopProxyInstance(target, serverType);//new AopControlProxy(target ,serverType) ;
return (MarshalByRefObject)rp.GetTransparentProxy();
}
#endregion
}
public class AopControlProxyFactory : IAopProxyFactory
{
#region IAopProxyFactory 成员
public AopProxyBase CreateAopProxyInstance(MarshalByRefObject obj, Type type)
{
return new AopControlProxy(obj, type);
}
#endregion
}
public class AopControlProxy : AopProxyBase
{
public AopControlProxy(MarshalByRefObject obj, Type type)
: base(obj, type) //指定调用基类中的构造函数
{
} public override void PreProcess(IMessage requestMsg)
{ Console.WriteLine("目标方法运行开始之前");
return;
} public override void PostProcess(IMessage requestMsg, IMessage Respond)
{
Console.WriteLine("目标方法运行结束之后");
}
public override IMessage Invoke(IMessage msg)
{
int useAspect = ;
string uselog = "";
IMethodCallMessage call = (IMethodCallMessage)msg; //查询目标方法是否使用了启用AOP的MethodAopSwitcherAttribute
foreach (Attribute attr in call.MethodBase.GetCustomAttributes(true))
{
MethodAopSwitcherAttribute mehodAopAttr = attr as MethodAopSwitcherAttribute;
if (mehodAopAttr != null)
{
useAspect = mehodAopAttr.UseAspect;
uselog = mehodAopAttr.Userlog; } if (useAspect == )
{
IMethodCallMessage callMsg = msg as IMethodCallMessage;
this.PostProcess(msg, callMsg); //执行方法之前的操作
}
if (useAspect == )
{
this.PreProcess(msg); //执行方法之前的操作
}
} #region 如果触发的是构造函数,此时target的构建还未开始
IConstructionCallMessage ctor = call as IConstructionCallMessage;
if (ctor != null)
{
//获取最底层的默认真实代理
RealProxy default_proxy = RemotingServices.GetRealProxy(this.target); default_proxy.InitializeServerObject(ctor);
MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy(); //自定义的透明代理 this return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctor, tp);
}
#endregion #region 调用目标方法代码
IMethodMessage result_msg;
result_msg = RemotingServices.ExecuteMessage(this.target, call);
#endregion //执行方法结束后的操作
this.PostProcess(msg, result_msg);
return result_msg; }
} public interface IExameplec
{ void say_hello(); void sayByeBye(); }
public class ExameplecProxy : IExameplec
{
public IExameplec exp { get; set; }
public ExameplecProxy(string a)
{
exp = new Exameplec(a);
} public void say_hello()
{
var t = Convert.ChangeType(exp, exp.GetType());
(t as dynamic).say_hello();
//((Exameplec)exp).say_hello();
}
public void sayByeBye()
{
exp.sayByeBye();
}
}
//如果在类上添加该代码 会导致没有添加属性的代码也会被带入Invoke中
//导致其他方法执行IMethodCallMessage callMsg = msg as IMethodCallMessage; return new ReturnMessage(callMsg.InArgs, null, 0, null, callMsg);
//最终导致其他方法的代码无法运行
[AopProxyAttribute(typeof(AopControlProxyFactory))] //将自己委托给AOP代理AopControlProxy,(最好不要添加该代码)
public partial class Exameplec : ContextBoundObject, IExameplec// //放到特定的上下文中,该上下文外部才会得到该对象的透明代理
{ private string name;
public Exameplec()
{ } public Exameplec(string a)
{
var t = this.GetType().GetMethod("say_hello").GetCustomAttributes(true)[] as MethodAopSwitcherAttribute;
this.name = a;
}
[MethodAopSwitcher(, "参数1")]
//[MethodAopSwitcher(2, "参数2")]
public void say_hello()
{
Console.WriteLine("say hello");
}
public void sayByeBye()
{
Console.WriteLine("say good bye");
}
} class Program
{
static void Main(string[] args)
{ ExameplecProxy epc = new ExameplecProxy("添加代理的方法");
epc.say_hello();
Console.WriteLine("");
Console.WriteLine("--------------------------这是分隔符--------------------------------"); //Exameplec epcs = new Exameplec("未添加代理的方法");
//epcs.sayByeBye();
//Console.WriteLine("--------------------------这是分隔符--------------------------------"); //Console.ReadLine();
}
}
}

.net 自定义AOP,透明代理与真实代理的更多相关文章

  1. .net 真实代理和透明代理的交互

    .本地代理调用 using System; using System.Runtime.Remoting ; using System.Runtime.Remoting.Services ; using ...

  2. 何为代理?jdk动态代理与cglib代理、spring Aop代理原理浅析

    原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...

  3. jdk动态代理与cglib代理、spring Aop代理原理-代理使用浅析

    原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...

  4. spring源码系列8:AOP源码解析之代理的创建

    回顾 首先回顾: JDK动态代理与CGLIB动态代理 Spring中的InstantiationAwareBeanPostProcessor和BeanPostProcessor的区别 我们得知 JDK ...

  5. nginx正向代理,反向代理,透明代理(总结)

    1正向代理 正向代理,也就是传说中的代理,他的工作原理就像一个跳板, 简单的说, 我是一个用户,我访问不了某网站,但是我能访问一个代理服务器 这个代理服务器呢,他能访问那个我不能访问的网站 于是我先连 ...

  6. jdk动态代理与cglib代理、spring aop代理实现原理

    原创声明:本博客来源与本人另一博客[http://blog.csdn.net/liaohaojian/article/details/63683317]原创作品,绝非他处摘取 代理(proxy)的定义 ...

  7. jdk动态代理与cglib代理、spring aop代理实现原理解析

    原创声明:本博客来源为本人原创作品,绝非他处摘取,转摘请联系博主 代理(proxy)的定义:为某对象提供代理服务,拥有操作代理对象的功能,在某些情况下,当客户不想或者不能直接引用另一个对象,而代理对象 ...

  8. java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总

    若代理类在程序运行前就已经存在,那么这种代理方式被成为 静态代理 ,这种情况下的代理类通常都是我们在Java代码中定义的. 通常情况下, 静态代理中的代理类和委托类会实现同一接口或是派生自相同的父类. ...

  9. (大型网站之Nginx)图解正向代理、反向代理、透明代理

    一.正向代理(Forward Proxy) 一般情况下,如果没有特别说明,代理技术默认说的是正向代理技术.关于正向代理的概念如下: 正向代理(forward)是一个位于客户端[用户A]和原始服务器(o ...

随机推荐

  1. JDK bin指令

    jmap: 一.调用命令示例: jmap -F-dump:format=b,file=rmsheap.bin 6086 就会在当前目录下生成rmsheap.bin的文件,6086是Pid.-F是在某些 ...

  2. 1106 Lowest Price in Supply Chain

    题意:略 思路:寻找树的叶结点中深度最低的,记录最低深度minDepth和具有相同最低深度的结点个数cnt. 代码: #include <cstdio> #include <cmat ...

  3. PyQt 5布局管理

    绝对定位 绝对定位有以下限制 1.如果调整窗口,控件的大小和位置不会改变 2.在各种平台上应用程序看起来不会一样 3.如果改变字体,我们的应用程序的布局就会改变 4.如果我们决定改变我们的布局,我们必 ...

  4. JeeSite导出多条数据(加复选框)demo

    表格图: jsp: 后台: @RequiresPermissions("shwindow:advertisementPutInList:view") @RequestMapping ...

  5. SQL Server 2008系统信息查询常用命令 查看表大小、记录数等

    1.返回所有数据库信息(数据库名,创建日期,存储路径等).   use master; GO select * from dbo.sysdatabases 2.返回当前数据库所有对象(可根据type字 ...

  6. ASP.NET MVC5入门指南

    1.创建项目 文件 --> 新建 --> 项目 Visual C# --> Web --> ASP.NET Web应用程序 MVC此时处于选中状态,勾选“添加单元测试”(可选择 ...

  7. SVN目录结构

    整理了一下svn目录结构,如下: 项目名称 ----branches    软件产品的迭代开发版本 ----tags        软件产品经过完整测试的历史稳定版本,已部署在客户机器上使用的 --- ...

  8. RSA_JS_PHP加密解密

    root@DESKTOP-I4OIMJC /cygdrive/e/html/RSA_JS_PHP/openssl/bin # ./openssl.exe OpenSSL> genrsa -out ...

  9. Splash Screen 加载窗体 [not finished]

    对于windows开 发人员来说在打开VS开发工具时,总是先呈现一个SplashScreen界面,登上几秒钟后才打开VS的主界面.这样的效果一般是在主界面需要加载大量 资源,为避免主界面变成“死”界面 ...

  10. PDO execute 执行错误

    PHP   PDO execute 执行错误,原因分析 $dbcon->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);或者 $db ...