.NET Core类库System.Reflection.DispatchProxy实现简易Aop的方法

2025-05-29 0 97

前言

aop即是面向切面编程,众多Aop框架里Castle是最为人所知的,另外还有死去的Spring.NET,当然,.NET Core社区新秀AspectCore在性能与功能上都非常优秀,已经逐渐被社区推崇和有越来越多的人使用。感谢柠檬同学的礼物!

如果大家出于自身需求或者学习,想实现一个Aop,是不是觉得一来就要使用Emit去做?最近我了解到了System.Reflection.DispatchProxy这个corefx类库,已经实现了动态代理功能。

1|1System.Reflection.DispatchProxy

下面演示一下它的使用方法:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32
class Program

{

static void Main(string[] args)

{

//创建代理类,并把SampleProxy作为拦截器注入

var sampleProxy = (targetInterface)SampleProxy.Create<targetInterface, SampleProxy>();

//执行接口方法

sampleProxy.Write("here is invoke by proxy");

}

}

//需要被生成代理实例的接口

public interface targetInterface

{

//这个方法会被代理类实现

void Write(string writesomeshing);

}

public class SampleProxy : DispatchProxy

{

/// <summary>

/// 拦截调用

/// </summary>

/// <param name="method">所拦截的方法信息</param>

/// <param name="parameters">所拦截方法被传入的参数指</param>

/// <returns></returns>

protected override object Invoke(MethodInfo targetMethod, object[] args)

{

Console.WriteLine(args[0]);

return null;

}

}

2|0改造成一款简易AOP

2|1为什么?

System.Reflection.DispatchProxy只有一个Api,就是objecct Create<T,TProxy>() where TProxy:DispatchProxy,约束了只能传入泛型参数,并不能从方法传入类型,这就会带来很多问题。而更可气的是,给官方提了issue之后,还是不给增加这个api……

2|2改造方法

幸好,在那个issue下,issue作者提供了一个解决方案,就是用反射来构造这个泛型方法。我还在这基础上,封装了一下,加入了传入拦截器实例和传入拦截器构造方法参数的功能。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
/// <summary>

/// 拦截器接口

/// </summary>

public interface IInterceptor

{

/// <summary>

/// 拦截器调用

/// </summary>

/// <param name="target">代理实例</param>

/// <param name="method">所拦截的方法</param>

/// <param name="parameters">所拦截方法传入的参数值</param>

/// <returns>返回值会传递给方法返回值</returns>

object Intercept(object target, MethodInfo method, object[] parameters);

}

拦截器要实现这个接口,下面是对DispatchProxy的封装,实现更多创建代理实例的方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68
public class ProxyGenerator : DispatchProxy

{

private IInterceptor interceptor { get; set; }

/// <summary>

/// 创建代理实例

/// </summary>

/// <param name="targetType">所要代理的接口类型</param>

/// <param name="interceptor">拦截器</param>

/// <returns>代理实例</returns>

public static object Create(Type targetType, IInterceptor interceptor)

{

object proxy = GetProxy(targetType);

((ProxyGenerator)proxy).CreateInstance(interceptor);

return proxy;

}

/// <summary>

/// 创建代理实例

/// </summary>

/// <param name="targetType">所要代理的接口类型</param>

/// <param name="interceptorType">拦截器类型</param>

/// <param name="parameters">拦截器构造函数参数值</param>

/// <returns>代理实例</returns>

public static object Create(Type targetType, Type interceptorType, params object[] parameters)

{

object proxy = GetProxy(targetType);

((ProxyGenerator)proxy).CreateInstance(interceptorType, parameters);

return proxy;

}

/// <summary>

/// 创建代理实例 TTarget:所要代理的接口类型 TInterceptor:拦截器类型

/// </summary>

/// <param name="parameters">拦截器构造函数参数值</param>

/// <returns>代理实例</returns>

public static TTarget Create<TTarget, TInterceptor>(params object[] parameters) where TInterceptor : IInterceptor

{

var proxy = GetProxy(typeof(TTarget));

((ProxyGenerator)proxy).CreateInstance(typeof(TInterceptor), parameters);

return (TTarget)proxy;

}

private static object GetProxy(Type targetType)

{

var callexp = Expression.Call(typeof(DispatchProxy), nameof(DispatchProxy.Create), new[] { targetType, typeof(ProxyGenerator) });

return Expression.Lambda<Func<object>>(callexp).Compile()();

}

private void CreateInstance(Type interceptorType, object[] parameters)

{

var ctorParams = parameters.Select(x => x.GetType()).ToArray();

var paramsExp = parameters.Select(x => Expression.Constant(x));

var newExp = Expression.New(interceptorType.GetConstructor(ctorParams), paramsExp);

this.interceptor = Expression.Lambda<Func<IInterceptor>>(newExp).Compile()();

}

private void CreateInstance(IInterceptor interceptor)

{

this.interceptor = interceptor;

}

protected override object Invoke(MethodInfo method, object[] parameters)

{

return this.interceptor.Intercept(method, parameters);

}

}

2|3使用方法

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36
class Program

{

static void Main(string[] args)

{

var poxy1 = (targetInterface)ProxyGenerator.Create(typeof(targetInterface), new SampleProxy("coreproxy1"));

poxy1.Write("here was invoked"); //---> "here was invoked by coreproxy1"

var poxy2 = (targetInterface)ProxyGenerator.Create(typeof(targetInterface), typeof(SampleProxy), "coreproxy2");

poxy2.Write("here was invoked"); //---> "here was invoked by coreproxy2"

var poxy3 = ProxyGenerator.Create<targetInterface, SampleProxy>("coreproxy3");

poxy3.Write("here was invoked"); //---> "here was invoked by coreproxy3"

}

}

public class SampleProxy : IInterceptor

{

private string proxyName { get; }

public SampleProxy(string name)

{

this.proxyName = name;

}

public object Intercept(MethodInfo method, object[] parameters)

{

Console.WriteLine(parameters[0] + " by " + proxyName);

return null;

}

}

public interface targetInterface

{

void Write(string writesome);

}

3|0总结

总结一下就是,微软爸爸给我们的这个轮子还是即轻便又很好用的。

本文的实例代码可以在我的github上找到:https://github.com/ElderJames/CoreProxy

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对快网idc的支持。

原文链接:https://www.cnblogs.com/ElderJames/p/implement-simple-Aop-using-a-dotnet-core-library-System-Reflection-DispatchProxy.html

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 .NET Core类库System.Reflection.DispatchProxy实现简易Aop的方法 https://www.kuaiidc.com/98162.html

相关文章

发表评论
暂无评论