zoukankan      html  css  js  c++  java
  • 用.net4中的DynamicObject实现简单AOP

             在.net framework 4中有一个DynamicObject 类型,我们通过重写 TryInvokeMember 方法实现简单的AOP

    首先看类图:

    Dynamicwarp

    看下面的代码:

     public class DynamicWrapper : DynamicObject
        {
            private readonly object source;
     
            public DynamicWrapper(object source)
            {
                this.source = source;
            }
     
            public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
            {
                var methodInfo = source.GetType().GetMethod(binder.Name);
                if (methodInfo != null)
                {
                    Func<object, object[], object> func = (s, a) => methodInfo.Invoke(s, a);
     
                    result = MethodCall(func, source, args);
     
                    return true;
                }
     
                result = null;
     
                return false;
            }
     
            protected virtual object MethodCall(Func<object, object[], object> func, object src, object[] args)
            {
                return func(src, args);
            }
        }

    我们在上面代码继承下加上一个TRY CATCH实现一个TryCatchDynamicWrapper:

        public class TryCatchDynamicWrapper : DynamicWrapper
        {
            public TryCatchDynamicWrapper(object source)
                : base(source)
            { }
     
            protected override object MethodCall(Func<object, object[], object> func, object src, object[] args)
            {
                try
                {
                    return base.MethodCall(func, src, args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    throw;
                }
     
            }
        }

       然后我们写一个简单的测试方法,输入两个数相除,类图如下:

    TestObject

    代码是这样的,这里我们增一个扩展方法,这样使我们的代码更加简洁,您会在后面的Unit Test中看到:

       1:      public interface ITestObject
       2:      {
       3:          int Div(int num1, int num2);
       4:      }
       5:   
       6:      public class TestObject : ITestObject
       7:      {
       8:   
       9:          #region ITestObject Members
      10:   
      11:          public int Div(int num1,int num2)
      12:          {
      13:              return num1 / num2;
      14:          }
      15:   
      16:          #endregion
      17:   
      18:          public ITestObject WrapDynamicConsoleLogging
      19:          {
      20:              get
      21:              {
      22:                  return this.WithMethodConsoleLogging();
      23:              }
      24:          }
      25:      }
      26:   
      27:      public static class Extenstions
      28:      {
      29:          public static dynamic WithMethodConsoleLogging(this ITestObject testobject)
      30:          {
      31:              return new DynamicLoggingWrapper(Activator.CreateInstance<TestObject>(), ConsoleLogger.Instance);
      32:          }
      33:   
      34:          public static dynamic WrapWith<T>(this ITestObject testobject) where T : DynamicWrapper
      35:          {
      36:              return Activator.CreateInstance(typeof(T), new object[] { Activator.CreateInstance<TestObject>() });
      37:          }
      38:      }

    Unit Test,如何使用呢:

       1:          [Test]
       2:          [ExpectedException(typeof(TargetInvocationException))]
       3:          public void TestTryCatchDynamicWrapper()
       4:          {
       5:              dynamic proxy = new TryCatchDynamicWrapper(new TestObject());
       6:              var ll = proxy.Div(6, 0);
       7:          }
       8:   
       9:          [Test]
      10:          [ExpectedException(typeof(TargetInvocationException))]
      11:          public void TestTryCatchDynamicWrapper2()
      12:          {
      13:              dynamic proxy = new TestObject().WrapWith<TryCatchDynamicWrapper>();
      14:              var ll = proxy.Div(6, 0);
      15:          }

    注意到代码故意产生Exception来检测AOP是否有效。第二个方法使用扩展方法看上去更加简洁。当我们还可以写一个泛型版本的,看类图:

    DynamicGenericarp

    代码是这样的:

        public class DynamicGenericWrapper<T> : DynamicObject where T : class
        {
            public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
            {
                var methodInfo = typeof(T).GetMethod(binder.Name);
                if (methodInfo != null)
                {
                    Func<object, object[], object> func = (s, a) => methodInfo.Invoke(s, a);
     
                    result = MethodCall<T>(func, args);
     
                    return true;
                }
     
                result = null;
     
                return false;
            }
     
            protected virtual object MethodCall<T>(Func<object, object[], object> func, object[] args)
            {
                var targetclass = Activator.CreateInstance<T>();
                return func(targetclass, args);
            }
        }
     
        public class TryCatchDynamicWrapper : DynamicWrapper
        {
            public TryCatchDynamicWrapper(object source)
                : base(source)
            { }
     
            protected override object MethodCall(Func<object, object[], object> func, object src, object[] args)
            {
                try
                {
                    return base.MethodCall(func, src, args);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    throw;
                }
     
            }
        }

    UnitTest:

       1:          [Test]
       2:          [ExpectedException(typeof(TargetInvocationException))]
       3:          public void TestTryCatchDynamicGenericWrapper()
       4:          {
       5:              dynamic proxy = new TryCatchDynamicGenericWrapper<TestObject>();
       6:              var ll = proxy.Div(6, 0);
       7:          }

    这样我们实现.NET4 了简单的异常处理。您还可以继承DynamicWrapper实现事务,日志等功能。

    您可以感兴趣文章:

    使用Unity2.0的Interceptor实现简单AOP

    使用EnterpriseLibrary的PIAB与Unity搭建简单AOP框架

    希望这篇POST对您开发有帮助!


    作者:Petter Liu
    出处:http://www.cnblogs.com/wintersun/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
    该文章也同时发布在我的独立博客中-Petter Liu Blog

  • 相关阅读:
    ORACLE分页SQL语句
    oracle中主键自增
    html5video初试牛刀api
    如何修改tomcat的端口号
    用Java来获取访问者真实的IP地址
    根据txt文件处理的方法总结
    CXF 做 webservice 简单例子demo
    java创建TXT文件并进行读、写、修改操作
    POJ1047 Round and Round We Go
    NYOJ305 表达式求值
  • 原文地址:https://www.cnblogs.com/wintersun/p/2084755.html
Copyright © 2011-2022 走看看