AOP精简框架

  在我之前的文章<<用代理技术实现简单的AOP框架>>里介绍了用RealProxy来实现AOP的方法拦截,由于Realproxy的效率较低,且被拦截的对象必须继承自ContextBoundObject,所以其有自身的局限性.为了更高效和在实际项目具有更好的实用性,我用装饰器模式,以面向接口的方式设计了一个简单的AOP框架,并在我的项目里广泛地应用,取得不错的实践效果.
AOP框架只包含三个类:
Decorate,用来对原来对象的方法,事件进行拦截.
DecorateFactory,用来构造拦截器的对象链的工厂
DecoratorAttribute,用来对被拦截对象的类的施加拦截器标识.


三个类的实现为:

/*
 * Author      :Nathan.Liu
 * Unit        :Decorate.cs
 * CopyRights  :Nathan.Liu
 * Email       :candylyg@sina.com
 * Description :
 * Story       :
 *      2007/11/16 create by nathan
 */
using System;
using System.Collections.Generic;
using System.Text;
using LYG.Share.Interface;

namespace LYG.Share.AOP.Decorator
{
    public interface IDecorate<T>
    {
        void InitDecorator(T obj, IDictionary<string, object> context);
        T Decorator { get; }
        IDictionary<string, object> Context { get;}
    }

    public abstract  class Decorate<T> : IDecorate<T>
    {
        private IDictionary<string, object> _context;
        public IDictionary<string, object> Context
        {
            get { return _context; }
        }
        T _decorator;
        public T Decorator
        {
            get { return _decorator; }
        }
        public virtual  void InitDecorator(T obj, IDictionary<string, object> context)
        {
            _decorator = obj;
            _context = context;
            LoadDecorator();
        }
        public abstract void LoadDecorator();
    }
}

/*
 * Author      :Nathan.Liu
 * Unit        :DecorateFactory.cs
 * CopyRights  :Nathan.Liu
 * Email       :candylyg@sina.com
 * Description :
 * Story       :
 *      2007/11/16 create by nathan
 */

using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using LYG.Share.Interface;
using LYG.Share .Exceptions ;

namespace LYG.Share.AOP.Decorator
{   
    public sealed class DecorateFactory<T> where T:class
    {
        private IDictionary<string,Type>  _types;
        private T _sourceObject;
        public DecorateFactory(T sourceObject)
        {
            _types = new Dictionary<string,Type>();
            _sourceObject = sourceObject;
            foreach (DecoratorAttribute attr in sourceObject.GetType().GetCustomAttributes(true))
            {
                this.AddType(attr.TypeList);
            }
        }
        private void AddType(Type type)
        {
            _types[type.FullName] = type;
        }
        private void AddType(Type[] typeList)
        {
            foreach (Type type in typeList)
                this.AddType(type);
        }

        private  T BuildInstance()
        {
            T result = _sourceObject ;
            IDictionary<string, object> context = new Dictionary<string, object>();
            foreach ( KeyValuePair<string,Type> pair in _types )
            {
                object obj = Activator.CreateInstance(pair .Value);
                if (obj is T)
                {
                    if (obj is IDecorate<T>)
                    {
                        ((IDecorate<T>)obj).InitDecorator(result,context );
                    }
                    result = (T)obj;
                }
            }
            return result;
        }
        public static T CreateInstance(T SourceObject)
        {
            return new DecorateFactory<T>(SourceObject).BuildInstance();
        }
        public static T CreateInstance(Type type,params object[] args )
        {
            object obj = Activator.CreateInstance(type,args);
            if (obj is T)
            {
                T tObj = obj as T;
                return new DecorateFactory<T>(tObj).BuildInstance();
            }
            else
                throw new SBException ("invalid instance type");
        }
    }
}


/*
 * Author      :Nathan.Liu
 * Unit        :DecoratorAttribute.cs
 * CopyRights  :Nathan.Liu
 * Email       :candylyg@sina.com
 * Description :
 * Story       :
 *      2007/11/16 create by nathan
 */

using System;
using System.Collections.Generic;
using System.Text;

namespace LYG.Share.AOP.Decorator
{
    [AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
    public class DecoratorAttribute:Attribute
    {
        public DecoratorAttribute(params Type[] types)
        {
            _typeList = types;
        }
        private Type[] _typeList;
        public Type[] TypeList
        {
            get { return _typeList; }
        }
    }
}

测试用例代码:
  public interface ISample
    {
        string GO();
    }
    [DecoratorAttribute(typeof(Test), typeof(Test2))]
    public class Sample : ISample
    {
        public string GO()
        {
            return "GO GO GO";
        }
    }
    public class Test : Decorate<ISample>, ISample
    {
        public string GO()
        {
            return "before decorate " + Decorator.GO() + " after decorate";
        }
        public override  void LoadDecorator()
        {
        }
    }
    public class Test2 : Decorate<ISample>, ISample
    {
        public string GO()
        {
            return "First Decorate " + Decorator.GO() + " Last Decorate";
        }
        public override   void LoadDecorator()
        {
        }
    }
    public class TestCase
    {
        public string Test()
        {
            ISample tt = DecorateFactory<ISample>.CreateInstance(new Sample());
            return tt.GO();
        }
    }





此AOP框架的优点是在于其执行的高效性,几乎没有性能损耗,并且可以实现多重的拦截,其对方法和事件的拦截顺序取决于拦截器被DecorateAttribute标记的顺序.此框架要求每个被拦截的类和拦截实现同一个接口,并且每个拦截器都需要实现对接口中的每个方法一个至少形式上的拦截,我不知道这算不算是一个缺点.总之,我在项目中用得很爽.

posted @ 2007-12-20 00:51  Nathan.Liu  阅读(2655)  评论(11编辑  收藏  举报