• 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. python核心编程第二版练习题答案

    2-5 #写一个while循环,输出整型为0~10 a=0while a<11: print a a+=1 #写一个for循环重复以上操作 for i in range(11): print i ...

  2. JavaScript Array对象

    介绍Js的Array 数组对象. 目录 1. 介绍:介绍 Array 数组对象的说明.定义方式以及属性. 2. 实例方法:介绍 Array 对象的实例方法:concat.every.filter.fo ...

  3. Android Ormlite 学习笔记1 -- 基础

    Ormlite 是一个开源Java数据实体映射框架.其中依赖2个核心类库: 1.ormlite-android-4.48.jar 2.ormlite-core-4.48.jar 新建项目,引用上面2个 ...

  4. 独立开发 一个社交 APP 的架构分享 (已实现)

    (本博客为原创:http://www.cnblogs.com/linguanh/)   My BananaCloud Android Application 前言:  这算是我的第一个 完完全全 由自 ...

  5. Java类访问权限修饰符

    一.概要 通过了解Java4种修饰符访问权限,能够进一步完善程序类,合理规划权限的范围,这样才能减少漏洞.提高安全性.具备表达力便于使用. 二.权限表 修饰符 同一个类 同一个包 不同包的子类 不同包 ...

  6. 树莓派 基于Web的温度计

    前言:家里的树莓派吃灰很久,于是拿出来做个室内温度展示也不错. 板子是model b型. 使用Python开发,web框架是flask,温度传感器是ds18b20 1 硬件连接 ds18b20的vcc ...

  7. Atitit 管理原理与实践attilax总结

    Atitit 管理原理与实践attilax总结 1. 管理学分类1 2. 我要学的管理学科2 3. 管理学原理2 4. 管理心理学2 5. 现代管理理论与方法2 6. <领导科学与艺术4 7. ...

  8. 前端开发小白必学技能—非关系数据库又像关系数据库的MongoDB快速入门命令(2)

    今天给大家道个歉,没有及时更新MongoDB快速入门的下篇,最近有点小忙,在此向博友们致歉.下面我将简单地说一下mongdb的一些基本命令以及我们日常开发过程中的一些问题.mongodb可以为我们提供 ...

  9. python_单元测试unittest

    Python自带一个单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 步骤1:首先引入unittest模块--import un ...

  10. Photoshop、Illustrator思维导图笔记

    半年前学习Photoshop时记得的思维导图笔记,可能不是很全,常用的基本都记下了.