• 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. IE的F12开发人员工具不显示问题

    按下F12之后,开发人员工具在桌面上看不到,但是任务栏里有显示.将鼠标放在任务栏的开发人员工具上,出现一片透明的区域,选中之后却出不来.将鼠标移动到开发人员工具的缩略图上,右键-最大化,工具就全屏出现 ...

  2. 开源一个跨平台运行的服务插件 - TaskCore.MainForm

    本次将要很大家分享的是一个跨平台运行的服务插件 - TaskCore.MainForm,此框架是使用.netcore来写的,现在netcore已经支持很多系统平台运行了,所以将以前的Task.Main ...

  3. ASP.NET从零开始学习EF的增删改查

           ASP.NET从零开始学习EF的增删改查           最近辞职了,但是离真正的离职还有一段时间,趁着这段空档期,总想着写些东西,想来想去,也不是很明确到底想写个啥,但是闲着也是够 ...

  4. mybatis_基础篇

    一.认识mybatis: MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改 ...

  5. zookeeper源码分析之一服务端启动过程

    zookeeper简介 zookeeper是为分布式应用提供分布式协作服务的开源软件.它提供了一组简单的原子操作,分布式应用可以基于这些原子操作来实现更高层次的同步服务,配置维护,组管理和命名.zoo ...

  6. 在Windows上编译和调试CoreCLR

    生成CoreCLR - Windows篇 本文的唯一目的就是让你运行Hello World 运行环境 Window 7+ Visual studio 2015 确保C++ 工具已经被安装,默认是不安装 ...

  7. npm 使用小结

    本文内容基于 npm 4.0.5 概述 npm (node package manager),即 node 包管理器.这里的 node 包就是指各种 javascript 库. npm 是随同 Nod ...

  8. 分布式学习系列【dubbo入门实践】

    分布式学习系列[dubbo入门实践] dubbo架构 组成部分:provider,consumer,registry,monitor: provider,consumer注册,订阅类似于消息队列的注册 ...

  9. css中line-height行高的深入学习

    之前对css中行高line-height的理解还是有些肤浅,深入后才发觉里面包罗万象.学习行高line-height,首先从基本原理开始 (标注该文章转载 http://www.cnblogs.com ...

  10. JavaScript中的this

    本文尽量避免概念性的讲解,那样太抽象 所以下面以一些简单的例子,从易到难对this的用法总结 1.方法中的this会指向当前执行该方法的对象 如: var name = "window&qu ...