在.net framework 4中有一个DynamicObject 类型,我们通过重写 TryInvokeMember 方法实现简单的AOP。
首先看类图:
看下面的代码:
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;}
}
}
然后我们写一个简单的测试方法,输入两个数相除,类图如下:
代码是这样的,这里我们增一个扩展方法,这样使我们的代码更加简洁,您会在后面的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是否有效。第二个方法使用扩展方法看上去更加简洁。当我们还可以写一个泛型版本的,看类图:
代码是这样的:
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实现事务,日志等功能。
您可以感兴趣文章:
使用EnterpriseLibrary的PIAB与Unity搭建简单AOP框架
希望这篇POST对您开发有帮助!
作者:Petter Liu
出处:http://www.cnblogs.com/wintersun/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
该文章也同时发布在我的独立博客中-Petter Liu Blog。



浙公网安备 33010602011771号