利用Attribute实现Aop

  Aop“面向切面编程”,与OOP“面向对象编程”一样是一种编程思路。个人理解:在不改变原有逻辑的基础上,注入其他行为。

  基础代码(仿MVC拦截器实现)

namespace HGL.Toolkit.Aop
{
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)]
    public sealed class AopAttribute : ContextAttribute, IContributeObjectSink
    {
        public AopAttribute() : base("Aop") { }

        //实现IContributeObjectSink接口当中的消息接收器接口
        public IMessageSink GetObjectSink(MarshalByRefObject obj, IMessageSink next)
        {
            return new AopProxy(next);
        }
    }

    [AttributeUsage(AttributeTargets.Method, AllowMultiple = true)]
    public class AopMethodAttribute : Attribute
    {
        /// <summary>
        /// 方法执行之前,执行代码
        /// </summary>
        public virtual bool OnMethodExecuting(System.Web.HttpContext context)
        {
            return true;
        }

        /// <summary>
        /// 方法执行之后,执行代码
        /// </summary>
        public virtual bool OnMethodExecuted(System.Web.HttpContext context)
        {
            return true;
        }
    }
}

namespace HGL.Toolkit.Aop
{
    public sealed class AopProxy : IMessageSink
    {
        //下一个接收器
        private IMessageSink nextSink;

        public IMessageSink NextSink
        {
            get { return nextSink; }
        }

        public AopProxy(IMessageSink nextSink)
        {
            this.nextSink = nextSink;
        }

        //同步处理方法
        public IMessage SyncProcessMessage(IMessage msg)
        {
            IMessage retMsg = null;

            //方法调用消息接口
            IMethodCallMessage call = msg as IMethodCallMessage;

            var attributes = Attribute.GetCustomAttributes(call.MethodBase, typeof(AopMethodAttribute));

            //如果被调用的方法没打AopMethodAttribute标签
            if (call == null || attributes.Count() == 0)
            {
                retMsg = nextSink.SyncProcessMessage(msg);
            }
            //如果打了AopMethodAttribute标签
            else
            {
                foreach (var attribute in attributes)
                {
                    var obj = attribute.GetType();

                    var executing = obj.GetMethod("OnMethodExecuting");
                    if (executing != null)
                    {
                        var context=System.Web.HttpContext.Current;
                        executing.Invoke(attribute, new object[] { context });
                    }
                }

                retMsg = nextSink.SyncProcessMessage(msg);

                foreach (var attribute in attributes)
                {
                    var obj = attribute.GetType();

                    var executed = obj.GetMethod("OnMethodExecuted");
                    if (executed != null)
                    {
                        var context = System.Web.HttpContext.Current;
                        executed.Invoke(attribute, new object[] { context });
                    }
                }
            }

            return retMsg;
        }

        //异步处理方法(不需要)
        public IMessageCtrl AsyncProcessMessage(IMessage msg, IMessageSink replySink)
        {
            return null;
        }
    }
}

  使用注意:

1.使用到Aop的类必须继承ContextBoundObject
2.使用到Aop的方法存在的类必须添加[Aop]特性
3.哪个方法需要实现Aop,就给那个方法添加[AopMethod]特性

AopMethod未实现任何业务逻辑,使用者需要重写该attribute

/// <summary>
/// 方法执行之前,执行代码
/// </summary>
public virtual bool OnMethodExecuting()
{
    return true;
}

/// <summary>
/// 方法执行之后,执行代码
/// </summary>
public virtual bool OnMethodExecuted()
{
    return true;
}
时间: 2024-10-20 08:29:37

利用Attribute实现Aop的相关文章

C# Unity依赖注入利用Attribute实现AOP功能

使用场景? 很多时候, 我们定义一个功能, 当我们要对这个功能进行扩展的时候, 按照常规的思路, 我们一般都是利用OOP的思想, 在原有的功能上进行扩展. 那么有没有一种东西, 可以实现当我们需要扩展这个功能的时候, 在不修改原来的功能代码的情况下实现, 这就是下面要说的到Unity. 1.准备工作 为项目添加NuGet包, 搜索Unity并且安装. 在使用的项目中添加Unity的相关引用 using Microsoft.Practices.Unity.InterceptionExtension

C#.NET利用ContextBoundObject和Attribute实现AOP技术--AOP事务实现例子

我前两天看见同事用写了用AOP技术实现缓存的方案,于是好奇看了一下这是怎么实现的.原来是用了.NET中的一个类ContextBoundObject和Attribute相关技术.其实个类在.NET Framework很早就有,至今才认识它,是有点相见恨晚的感觉.网上一搜,已经有了很多使用ContextBoundObject类实现AOP的例子,其中我就看到一篇利用ContextBoundObject和Attribute实现AOP事务实现例子,我想应该和实现AOP缓存是一个道理.下面我就把这篇文章分享

mvc中利用Attribute特性来进行进行简单的登陆验证

前段时间一直比较忙.好不容易忙完.闲的没事干,就捣腾了下mvc(ef),因为以前都是用三层框架来进行开发,mvc用的也不是很多...众所周知,在三层里面我们一般都是建一个基类,然后在基类里面写验证登录方法,然后在需要验证登录的页面继承这个基类即可...但到了mvc里面所有的视图页面的操作都转移到了控制器了..这个时候我们在按照三层的方式建一个基类来继承验证登录,就没办法走通了...今天我就给大家来展示一个利用Attribute特性来验证登录.如果还有不知道这个东东的,可以百度一下Attribut

Java入门到精通——调错篇之Spring2.5利用aspect实现AOP时报错: error at ::0 can&#39;t find referenced pointcut XXX

一.问题描述及原因. 利用Aspect注解实现AOP的时候出现了error at ::0 can't find referenced pointcut XXX.一看我以为注解写错了,结果通过查询相关资料是因为Spring2.5与中的aspectjweaver.jar 和aspectjrt.jar这两个jar包与JDK1.7不匹配. org.springframework.beans.factory.BeanCreationException: Error creating bean with n

C#当中利用Attribute实现简易AOP

首先看一段简单的代码: public partial class Form1 : Form { public Form1() { InitializeComponent(); } //来自UI层的调用 private void button1_Click(object sender, EventArgs e) { BusinessHandler handler = new BusinessHandler(); handler.DoSomething(); } } //业务层的类和方法 publi

利用Unity实现AOP

.NET程序中,可以利用Unity来实现AOP,用来进行日志.缓存或权限的处理.这里我们来写一个简单的程序,让其实现简单的AOP功能. 1.使用NuGet,在项目中获取Microsoft.Practices.Unity. 2.新建一个ITalk类及其实现 public interface ITalk { string Speak(string msg); } public class Talk : ITalk { public string Speak(string msg) { Console

利用Attribute和IErrorHandler处理WCF全局异常

在处理WCF异常的时候,有大概几种方式: 第一种是在配置文件中,将includeExceptionDetailInFaults设置为true <behavior name="serviceDebuBehavior"><serviceDebug includeExceptionDetailInFaults="true" /></behavior> 但是这种方式会导致敏感信息泄漏的危险,一般我们仅仅在调试的时候才开启该属性,如果已经发

利用Cglib实现AOP

Cglib可以为对象加上动态代理, 实现代码切入, 但是每次调用比较繁琐, 因此我们还需要给他加了一层语法糖, 使之更易用. Advice Spring带了一堆Advice, 我们只模拟实现环绕Advice, 以及增加了一个Clear切入的注解, 下面看具体实现. 1 /** 2 * 环绕Advie 3 * 4 * 可以加在类上, 或者方法上. 5 * 加在类上的话, 类中所有无@Clear注解的方法都会被切入 6 * 7 * @Before({CustomInterceptor.class,

Spring(三)——AOP

AOP全名为Aspect-Oriented Programming,意思是面向横切面编程,前边我们有过介绍   面向横切面编程AOP的理解 ,我们通过这种编程思想很容易的扩展我们的应用程序. 一,如何实现AOP编程思想呢?实现这种编程思想的一个重要手段就是代理模式或者说模仿代理模式的运用.尤其是其中动态代理模式,JDK提供的Proxy的使用,这个在前边也总结:Proxy代理模式的应用                       而这种动态代理是基于接口的,也就是说代理对象和目标对象实现了同一个接