• RealProxy基本代理类

    RealProxy类提供代理的基本功能。这个类中有一个GetTransparentProxy方法,此方法返回当前代理实例的透明代理。这是我们AOP实现的主要依赖。

    新建一个代理类MyProxy继承RealProxyIIntercept是我们自己实现的拦截器接口,内部只有一个Do方法

        private object _target; //当前代理实例
        private List<IIntercept> _intercepts; //拦截器
        MyProxy(object target, Type type,params IIntercept[] intercepts) : base(type)
        {
            _target = target;
            _intercepts = intercepts!=null? intercepts.ToList():null;
        }

    RealProxyInvoke方法会执行当前代理实例中方法,所以我们可以重写Invoke来实现AOP

    public override IMessage Invoke(IMessage msg)
    {
        var ctr = msg as IConstructionCallMessage;
        if (ctr != null)//执行构造函数
        {
            Console.WriteLine("Construction");
            RealProxy _proxy = RemotingServices.GetRealProxy(this._target);
            _proxy.InitializeServerObject(ctr);
            MarshalByRefObject tp = (MarshalByRefObject)this.GetTransparentProxy();
            return EnterpriseServicesHelper.CreateConstructionReturnMessage(ctr, tp);
        }
        //执行当前代理实例方法
        if(_intercepts!=null)
        {
            foreach (var _intercept in _intercepts)
            {
                _intercept.Do();
            }
        }
        var call = msg as IMethodCallMessage;
        Console.WriteLine(string.Format("proxy method:{0}", call.MethodName));
        var result = call.MethodBase.Invoke(this._target,call.Args);
        return new ReturnMessage(result,new object[0],0,null,call);
    }

    封装代理类的实现,注意:RealProxy构造函数要求目标代理类必须必须从 MarshalByRef类型派生,所以我们需要继承 MarshalByRefObject类或者 ContextBoundObject

    public static class ActivatorContainer
    {
        public static T Create<T>(params IIntercept[] intercepts)
        {
             //构造函数不会被代理
            var result= Activator.CreateInstance(typeof(T));
            var myProxy = new MyProxy(result, typeof(T), intercepts);
            return (T)myProxy.GetTransparentProxy();
        }
    }
    
    var log = new LogIntercept();
    var time = new TimeIntercept();
    var hance = ActivatorContainer.Create<Person>(log,time);
    hance.Say("hello Proxy");

    运行结果:

    熟悉Castle的动态代理的同学可能会发现,我们自己实现的就像Castle的简易版,基于上面的代码我们也可以实现一个完善的动态代理

  • ProxyAttribute特性

    ProxyAttribute特性标志指示对象类型需要自定义代理。使用特性的相当于代替了上面的ActivatorContainer静态类来自动实现类的代理

    [AttributeUsage(AttributeTargets.Class)]
    public class MyProxyAttribute : ProxyAttribute
    {
        private List<Type> _types; //拦截器
        //注:特性参数限制于bool, byte, char, double, float, int, long, short, string, System.Type, object, enum。
        public MyProxyAttribute(params Type[] types)
        {
            _types = types?.ToList();
        }
        public override MarshalByRefObject CreateInstance(Type serverType)
        {
            System.Console.WriteLine("Start!");
            var target= base.CreateInstance(serverType);
            List<IIntercept> intercepts = null;
            if (_types!=null)
            {
                intercepts = new List<IIntercept>();
                intercepts.AddRange(_types.Select(s =>
                {
                    return (IIntercept)Activator.CreateInstance(s);
                }));
            }
            var myProxy = new MyProxy(target, serverType, intercepts?.ToArray());
            return (MarshalByRefObject)myProxy.GetTransparentProxy();
        }
    }

    此时,我们只要在需要代理的类上加上MyProxyAttribute标志,代理类需要继承 ContextBoundObject类,而不能是 MarshalByRefObject,然后直接new相关类就行了。此种实现方式构造函数也会被代理,可以通过特性参数注入拦截器类型来实现相关拦截器,相对于直接new拦截器来说更为方便,但不够灵活。但有一个好处就是如果没有继承ContextBoundObject类,目标类不会被代理,也不会不会报错。而上面的实现方式如果没有继承MarshalByRefObject类,运行则会报错。

    var hance = new Person();
    hance.Say("hello");

    运行结果:

在.Net中实现自己的简易AOP的更多相关文章

  1. 在.NET项目中使用PostSharp,实现AOP面向切面编程处理

    PostSharp是一种Aspect Oriented Programming 面向切面(或面向方面)的组件框架,适用在.NET开发中,本篇主要介绍Postsharp在.NET开发中的相关知识,以及一 ...

  2. JavaEE开发之Spring中的依赖注入与AOP

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  3. JavaEE开发之Spring中的依赖注入与AOP编程

    上篇博客我们系统的聊了<JavaEE开发之基于Eclipse的环境搭建以及Maven Web App的创建>,并在之前的博客中我们聊了依赖注入的相关东西,并且使用Objective-C的R ...

  4. 利用.NET Core类库System.Reflection.DispatchProxy实现简易Aop

    背景 Aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社 ...

  5. ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍

    如果我是C罗 原文 ORACLE PL/SQL 中序列(sequence)的简易使用方法介绍 sequence在ORACLE中应用十分广泛,就是序列号的意思,会自动增加指定变数,如逐次增加1或者2或者 ...

  6. js中的经典案例--简易万年历

    js中的经典案例--简易万年历 html代码 <!DOCTYPE html> <html> <head> <meta charset="utf-8& ...

  7. [译]如何在ASP.NET Core中实现面向切面编程(AOP)

    原文地址:ASPECT ORIENTED PROGRAMMING USING PROXIES IN ASP.NET CORE 原文作者:ZANID HAYTAM 译文地址:如何在ASP.NET Cor ...

  8. Spring同一个类中的注解方法调用AOP失效问题总结

    public interface XxxService { // a -> b void a(); void b(); } @Slf4j public class XxxServiceImpl ...

  9. C#利用Attribute实现简易AOP介绍

    首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 ...

随机推荐

  1. 关于自己写C++的一点风格

    现在,我学了很长时间的C++,但是自己就是无法精通.许多知识是入门书上没有的.现在写C++最重要的就是风格问题. 我现在的C++风格: 把自己所有的东西都放在一个名称空间下. 没有全局的函数,有的函数 ...

  2. Linux CentOS 配置JDK环境

    一.下载JDK 下载JDK的方式有两种: 1.Linux中使用wget下载 1.使用命令安装wget yum install wget 2.下载 wget 'http://download.oracl ...

  3. Nginx学习笔记--001-Nginx快速搭建

    Nginx ("engine x") 是一个高性能的HTTP和反向代理服务器,也是一个IMAP/POP3/SMTP服务器.Nginx是由Igor Sysoev为俄罗斯访问量第二的R ...

  4. webpack学习总结

    前言 在还未接触webpack,就有几个疑问: 1. webpack本质上是什么? 2. 跟异步模块加载有关系吗? 3. 可否生成多个文件,一定是一个? 4. 被引用的文件有其他异步加载模块怎么办? ...

  5. 浅谈SQL注入风险 - 一个Login拿下Server

    前两天,带着学生们学习了简单的ASP.NET MVC,通过ADO.NET方式连接数据库,实现增删改查. 可能有一部分学生提前预习过,在我写登录SQL的时候,他们鄙视我说:“老师你这SQL有注入,随便都 ...

  6. VIM教程

    vim 的环境设定参数 :set nu :set nonu             就是设定与取消行号啊! :set hlsearch :set nohlsearch     hlsearch 就是 ...

  7. MyEclipse对Maven的安装

    好记性不如烂笔头,记录一下. 操作系统:windows 7 MyEclipse2015 JDK1.7 maven的下载链接,点这里下载apache-maven-3.0.4-bin.tar.gz. 下载 ...

  8. [bzoj2152][聪聪和可可] (点分治+概率)

    Description 聪聪和可可是兄弟俩,他们俩经常为了一些琐事打起来,例如家中只剩下最后一根冰棍而两人都想吃.两个人都想玩儿电脑(可是他们家只有一台电脑)……遇到这种问题,一般情况下石头剪刀布就好 ...

  9. DBCP 配置备注

    <property name="initialSize" value="5"></property> <property name ...

  10. WCF : 修复 Security settings for this service require Windows Authentication but it is not enabled for the IIS application that hosts this service 问题

    摘要 : 最近遇到了一个奇怪的 WCF 安全配置问题, WCF Service 上面配置了Windows Authentication. IIS上也启用了 Windows Authentication ...