在《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类注入到容器中。

.NET Core依赖注入集成Dynamic Proxy的更多相关文章

  1. Webservice WCF WebApi 前端数据可视化 前端数据可视化 C# asp.net PhoneGap html5 C# Where 网站分布式开发简介 EntityFramework Core依赖注入上下文方式不同造成内存泄漏了解一下? SQL Server之深入理解STUFF 你必须知道的EntityFramework 6.x和EntityFramework Cor

    Webservice WCF WebApi   注明:改编加组合 在.net平台下,有大量的技术让你创建一个HTTP服务,像Web Service,WCF,现在又出了Web API.在.net平台下, ...

  2. # ASP.NET Core依赖注入解读&使用Autofac替代实现

    标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Aut ...

  3. NET Core依赖注入解读&使用Autofac替代实现

    NET Core依赖注入解读&使用Autofac替代实现 标签: 依赖注入 Autofac ASPNETCore ASP.NET Core依赖注入解读&使用Autofac替代实现 1. ...

  4. ASP.NET Core依赖注入解读&使用Autofac替代实现【转载】

    ASP.NET Core依赖注入解读&使用Autofac替代实现 1. 前言 2. ASP.NET Core 中的DI方式 3. Autofac实现和自定义实现扩展方法 3.1 安装Autof ...

  5. 探索 .NET Core 依赖注入的 IServiceProvider

    在上一篇文章中,我们学习了Microsoft.Extensions.DependencyInjection中的IServiceCollection,包括服务注册转换为ServiceDescriptor ...

  6. net core 依赖注入问题

    net core 依赖注入问题 最近.net core可以跨平台了,这是一个伟大的事情,为了可以赶上两年以后的跨平台部署大潮,我也加入到了学习之列.今天研究的是依赖注入,但是我发现一个问题,困扰我很久 ...

  7. 实现BUG自动检测 - ASP.NET Core依赖注入

    我个人比较懒,能自动做的事绝不手动做,最近在用ASP.NET Core写一个项目,过程中会积累一些方便的工具类或框架,分享出来欢迎大家点评. 如果以后有时间的话,我打算写一个系列的[实现BUG自动检测 ...

  8. [译]ASP.NET Core依赖注入深入讨论

    原文链接:ASP.NET Core Dependency Injection Deep Dive - Joonas W's blog 这篇文章我们来深入探讨ASP.NET Core.MVC Core中 ...

  9. asp.net core 依赖注入几种常见情况

    先读一篇注入入门 全面理解 ASP.NET Core 依赖注入, 学习一下基本使用 然后学习一招, 不使用接口规范, 直接写功能类, 一般情况下可以用来做单例. 参考https://www.cnblo ...

随机推荐

  1. Web Scraper 翻页——利用 Link 选择器翻页 | 简易数据分析 14

    这是简易数据分析系列的第 14 篇文章. 今天我们还来聊聊 Web Scraper 翻页的技巧. 这次的更新是受一位读者启发的,他当时想用 Web scraper 爬取一个分页器分页的网页,却发现我之 ...

  2. Vue 幸运大转盘

    转盘抽奖主要有两种,指针转动和转盘转动,个人觉得转盘转动比较好看点,指针转动看着头晕,转盘转动时指针是在转盘的中间位置,这里要用到css的transform属性和transition属性,这两个因为不 ...

  3. CBO优化器实用理解

    对于CBO的理解: RBO-----基于规则的优化器 CBO-----基于代价的优化器 CBO计算执行计划的代价(cost),并从中选择cost最低的执行方案,它依赖数据库对象的统计信息,统计信息的及 ...

  4. Kotlin协程通信机制: Channel

    Coroutines Channels Java中的多线程通信, 总会涉及到共享状态(shared mutable state)的读写, 有同步, 死锁等问题要处理. 协程中的Channel用于协程间 ...

  5. Django中间件部分源码分析

    中间件源码分析 中间件简介 中间件是一个用来处理Django的请求和响应的框架级别的钩子.它是一个轻量.低级别的插件系统,用于在全局范围内改变Django的输入和输出.每个中间件组件都负责做一些特定的 ...

  6. python模块IO

    Python之模块IO io概叙 io模块提供了python用于处理各种类型I/O的主要工具,主要有三种类型的I/O:文本I/O,二进制I/O和原始I/O:这些都是通用类型,各种后备存储可使用其中的每 ...

  7. ThinkPHP3.2.2实现持久登录(记住我)功能的方法

    实现持久登录,即用户在登录时,勾选了"记住我"之后,无论是否关闭浏览器,只要不退出登录,在指定的时间内始终保持登录状态(缺点是在另一台电脑上登录过后,之前那台电脑就不能继续保持登录 ...

  8. Netty学习——服务器端代码和客户端代码 原理详解

    服务器端代码和客户端代码 原理详解:(用到的API) 0.Socket 连接服务器端的套接字 1.TcompactProtocol   协议层2.TFrameTransport   传输层3.THsh ...

  9. 图解leetcode —— 124. 二叉树中的最大路径和

    前言: 每道题附带动态示意图,提供java.python两种语言答案,力求提供leetcode最优解. 描述: 给定一个非空二叉树,返回其最大路径和. 本题中,路径被定义为一条从树中任意节点出发,达到 ...

  10. ubuntu部署.Net Core3.1(Nginx+pm2)

    前言 虽然.NetCore已经出来很久了,但是很多初学者还是不会在linux部署.所以写一篇初学者在ubuntu下部署Core的全过程,大佬请无视. 环境搭建 ubuntu18.04 NetCore3 ...