在《Castle DynamicProxy基本用法》中介绍了如何将DP与Autofac集成使用,而 .NET Core有自己的依赖注入容器,在不依赖第三方容器的基础上,如何实现动态代理就成了一个问题。

.NET Core依赖注入实现动态代理

我们知道,要创建一个代理对象,需要简单的三步:

  • 创建Target
  • 创建Interceptor
  • 使用Target和Interceptor创建代理对象

.NET Core的依赖注入允许我们自定义ServiceDescriptor对象,而在ServiceDescriptor对象中,我们可以定义对象实例化的过程,这个过程叫做factory,通过自定义factory,我们可以类型的动态代理的创建。

代码如下:

services.AddTransient<LoggingInterceptor>();
services.AddTransient<SampleService>(); services.AddTransient<ISampleService>(provider =>
{
var target = provider.GetService<SampleService>();
var loggingInterceptor = provider.GetService<LoggingInterceptor>();
var proxy = DynamicProxyExtensions.Generator.CreateInterfaceProxyWithTarget<ISampleService>(target, loggingInterceptor); return proxy;
});

或者通过实例化ServiceDescriptor的方式进行注入:

services.AddTransient<LoggingInterceptor>();
services.AddTransient<SampleService>(); Func<IServiceProvider, object> factory = (provider) => {
var target = provider.GetService<SampleService>();
var loggingInterceptor = provider.GetService<LoggingInterceptor>();
var auditInterceptor = provider.GetService<AuditInterceptor>().ToInterceptor();
var proxy = DynamicProxyExtensions.Generator.CreateInterfaceProxyWithTarget<ISampleService>(target, loggingInterceptor, auditInterceptor); return proxy;
};
var serviceDescriptor = new ServiceDescriptor(typeof(ISampleService), factory, ServiceLifetime.Transient); services.Add(serviceDescriptor);

通过这种方式,我们可以将动态代理与依赖注入结合起来。但是这样的代码缺少封装,开发效率偏低,在使用过程中还需要对依赖注入、动态代理都有一定了解,为了解决这些问题,我们需要再次封装。

依赖注入与动态代理的简单封装

public static class DependencyInjectionExtensions
{
public static IServiceCollection AddService<TService, TImplementation>(this IServiceCollection services,
ServiceLifetime lifetime, params Type[] interceptorTypes)
{
return services.AddService(typeof(TService), typeof(TImplementation), lifetime, interceptorTypes);
} public static IServiceCollection AddService(this IServiceCollection services, Type serviceType, Type implType,
ServiceLifetime lifetime, params Type[] interceptorTypes)
{
services.Add(new ServiceDescriptor(implType, implType, lifetime)); Func<IServiceProvider, object> factory = (provider) =>
{
var target = provider.GetService(implType); List<IInterceptor> interceptors = interceptorTypes.ToList().ConvertAll<IInterceptor>(interceptorType =>
{
return provider.GetService(interceptorType) as IInterceptor;
}); var proxy = DynamicProxyExtensions.Generator.CreateInterfaceProxyWithTarget(serviceType, target, interceptors.ToArray()); return proxy;
};
var serviceDescriptor = new ServiceDescriptor(serviceType, factory, lifetime);
services.Add(serviceDescriptor); return services;
}
}

在使用时需要注意,一定要先将Interceptor类注入到容器中。

最新文章

  1. iOS 原生态扫描二维码、条形码的功能。
  2. css小技巧之去掉蓝色底块的方法
  3. zookeeper3.4.6的安装
  4. Django教程:第一个Django应用程序(4)
  5. Android 颜色渲染(九) PorterDuff及Xfermode详解
  6. 去掉matlab图片空白边缘
  7. Windows使用小技巧
  8. 10款面向HTML5 画布(Canvas)的JavaScript库
  9. 手机PC监听用户复制内容
  10. 【Python实战】模块和包导入详解(import)
  11. structure
  12. 【xsy2479】counting 生成函数+多项式快速幂
  13. C#中的Action和Func和Predicate
  14. 【读书笔记】iOS-发布你的应用
  15. PhysX Clothing for UE4
  16. unigui的编译部署
  17. 【转】Fiddler工作原理
  18. iOS常用RGB颜色的色值表
  19. linux nginx,php开机启动
  20. Js中split()方法的正确使用

热门文章

  1. ArcGIS 切片与矢量图图层顺序问题
  2. Parallel Feature Pyramid Network for Object Detection
  3. Markdown学习笔记(一)
  4. MySQL8.0 新特性 Hash Join
  5. 复制节点(cloneNode)
  6. System.out.printf使用以及注意点
  7. java 获取当前年份 月份 日期
  8. VS #region
  9. 交互程序 Scanner类
  10. python20个骚操作