Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

castle.dynamicproxy.md 3.9 KiB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # 和 Castle DynamicProxy 集成
  2. Castle DynamicProxy 是一个用于在运行时动态生成轻量级.NET代理的库。代理对象允许在不修改类代码的情况下截取对对象成员的调用。可以代理类和接口,但是只能拦截虚拟成员。
  3. Castle.DynamicProxy 可以帮助你方便的创建代理对象,代理对象可以帮助构建灵活的应用程序体系结构,因为它允许将功能透明地添加到代码中,而无需对其进行修改。例如,可以代理一个类来添加日志记录或安全检查,而无需使代码知道已添加此功能。
  4. 下面可以看到如何在 CAP 中集成使用 Castle.DynamicProxy。
  5. ## 1、安装 NuGet 包
  6. 在 集成了 CAP 的项目中安装包,有关如何集成 CAP 的文档请看[这里](https://cap.dotnetcore.xyz/)。
  7. 注意,`Castle.DynamicProxy` 这个包已经被废弃,请使用最新的 `Castle.Core` 包。
  8. ```xml
  9. <PackageReference Include="Castle.Core" Version="4.4.1" />
  10. ```
  11. ## 2、创建一个 Castle 切面拦截器
  12. 可以在这里 [dynamicproxy.md](https://github.com/castleproject/Core/blob/master/docs/dynamicproxy.md) 找到相关的文档。
  13. 下面为示例代码,继承 Castle 提供的 `IInterceptor` 接口即可:
  14. ```
  15. [Serializable]
  16. public class MyInterceptor : IInterceptor
  17. {
  18. public void Intercept(IInvocation invocation)
  19. {
  20. Console.WriteLine("Before target call");
  21. try
  22. {
  23. invocation.Proceed();
  24. }
  25. catch (Exception)
  26. {
  27. Console.WriteLine("Target threw an exception!");
  28. throw;
  29. }
  30. finally
  31. {
  32. Console.WriteLine("After target call");
  33. }
  34. }
  35. }
  36. ```
  37. 拦截器此处命名为 `MyInterceptor`,你可以在其中处理你的业务逻辑,比如添加日志或其他的一些行为。
  38. ## 3、创建 IServiceCollection 的扩展类
  39. 为 `IServiceCollection` 创建扩展,方面后续调用。
  40. ```csharp
  41. using Castle.DynamicProxy;
  42. public static class ServicesExtensions
  43. {
  44. public static void AddProxiedSingleton<TImplementation>(this IServiceCollection services)
  45. where TImplementation : class
  46. {
  47. services.AddSingleton(serviceProvider =>
  48. {
  49. var proxyGenerator = serviceProvider.GetRequiredService<ProxyGenerator>();
  50. var interceptors = serviceProvider.GetServices<IInterceptor>().ToArray();
  51. return proxyGenerator.CreateClassProxy<TImplementation>(interceptors);
  52. });
  53. }
  54. }
  55. ```
  56. 此处我创建了一个 Singleton 声明周期的扩展方法,建议所有 CAP 的订阅者都创建为 Singleton 即可,因为在 CAP 内部实际执行的时候也会创建一个 scope 来执行,所以无需担心资源释放问题。
  57. ## 4、创建 CAP 订阅服务
  58. 创建一个 CAP 订阅类,注意不能放在 Controller 中了。
  59. **注意:方法需要为虚方法 virtual,才能被 Castle 重写,别搞忘了加!!!**
  60. ```cs
  61. public class CapSubscribeService: ICapSubscribe
  62. {
  63. [CapSubscribe("sample.rabbitmq.mysql")]
  64. public virtual void Subscriber(DateTime p)
  65. {
  66. Console.WriteLine($@"{DateTime.Now} Subscriber invoked, Info: {p}");
  67. }
  68. }
  69. ```
  70. ## 5、在 Startup 中集成
  71. ```cs
  72. public void ConfigureServices(IServiceCollection services)
  73. {
  74. // 添加 Castle 的代理生成器
  75. services.AddSingleton(new ProxyGenerator());
  76. // 添加第2步的自定义的拦截类,声明周期为
  77. services.AddSingleton<IInterceptor, MyInterceptor>();
  78. // 此处为上面的扩展方法, 添加 CAP 订阅 Service
  79. services.AddProxiedSingleton<CapSubscribeService>();
  80. services.AddCap(x =>
  81. {
  82. x.UseMySql("");
  83. x.UseRabbitMQ("");
  84. x.UseDashboard();
  85. });
  86. // ...
  87. }
  88. ```
  89. 以上就完成了所有的集成工作,可以开始进行测试了,有问题欢迎到 [Github issue](https://github.com/dotnetcore/CAP/issues) 反馈。
  90. **注意: CAP 需要使用 5.0 + 版本,目前(2021年1月6日)只有 preview 版本。**