首页 > 其他分享 >聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)

聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)

时间:2024-01-13 20:23:08浏览次数:32  
标签:Core ISampleService 聊一聊 Extensions var Castle Microsoft SampleService

聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)

  合集 - 聊一聊如何整合Microsoft默认的Ioc容器和Castle.Core(4)   1.整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)01-12 2.聊一聊如何结合Microsoft.Extensions.DependenyInjection和Castle.Core01-123.聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(三)01-124.整合Microsoft.Extensions.DependencyInjection和Castle.Core(完结篇)01-13 收起  

聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)

前言

前文排版比较糟糕,这次我们使用vscode来写本文,,各位看客请见谅。
上文描述了 ServiceDescriptor 的三种构造形式,这决定了我们之后获取原始对象要考虑的场景,至于如何获取暂且不表,在实现细节部分我们会详细阐述。
本文将阐述 _ProxyGenerator_的一些细节,以便各位看客更好理解 Castle 在各种场景下 如何选择合适的接口去构建代理对象(以下全称为代理对象或者 proxy

代理对象的构建方法

大体分成两种方式 一种是具体类 一种是根据接口生成代理对象,每种内部都会区分是否传入原始对象 看方法签名 WithTarget 即需要传入 原始对象,WithoutTarget 即不需要传入原始对象,

  • ProxyGenerator.CreateClassProxy
  • ProxyGenerator.CreateInterfaceProxy

示例说明

接下来我们以几种示例来介绍各个接口的使用情况

  • 假设已知 一个接口 ISampleService 和一个实现类 SampleService
public class SampleService : ISampleService
{
  public virtual Task  ShowAsync()
  {
    return Task.CompletedTask;
  }
}

public interface ISampleService 
{
   Task ShowAsync();
}

public class Interceptor : IInterceptor
{
    public  void Intercept(IInvocation invocation)
    {
        Console.WriteLine("Interceptor  starting...");
        invocation.Proceed();
        Console.WriteLine("Interceptor  ended...");
    }
}

具体类

image

我们想对 SampleService 进行代理生成 因为 SampleService 具有无参构造,所以我们可以这样

var generator=new ProxyGenerator();
var proxy = generator.CreateClassProxy(typeof(SampleService), new Interceptor());

image

假设 SampleService 有参数构造函数

public class SampleService : ISampleService
{
    private readonly ILogger<SampleService> _logger;
    public SampleService(ILogger<SampleService> logger)
    {
        _logger=logger;
    }
    public Task ShowAsync()
    {
        return Task.CompletedTask;
    }
}
```,那么我们就可以这样
``` csharp
var generator=new ProxyGenerator();
var  sampleSvc=sp.GetRequiredService<SampleService>();
var proxy = generator.CreateClassProxyWithTarget(typeof(SampleService),sampleSvc, new Interceptor());

细心的朋友可能发现这时候我们引入了一个变量 而我们并未定义,
这时候我们添加如下代码:

    var services=new ServiceCollection();
    services.AddLogging();//此处添加日志服务 伪代码 以便获取ILogger<SampleService>
    services.AddSingleton<ProxyGenerator>(sp=>new ProxyGenerator());
    servies.TryAddTransient<SampleService>();
    var sp=services.BuildServiceProvider();

接口

使用以上代码示例,假设我们要对 ISampleService 进行代理生成,那么我们就可以这样
image

services.TryAddTransient<ISampleService, SampleService>();//注入阶段添加以下代码以便获取ISampleService
var generator=sp.GetRequiredService<ProxyGenerator>();
var proxy=generator.CreateInterfaceProxyWithoutTarget(typeof(ISampleService),new Interceptor());//因为没有传入 原始对象,所以依然要求我们是一个无参构造的实现 TODO:可自行验证

看下原始定义

假设我们获取了 _ISampleService_的实例

var  sampleSvc=sp.GetRequiredService<ISampleService>();
var proxy = generator.CreateInterfaceProxyWithTarget(typeof(ISampleService),sampleSvc, new Interceptor());

image

可以发现 接口代理 和具体类代理 基本相似
细心的可以注意到 SampleService.ShowAsync 很反常的 加了个关键字 virtual,想知道为什么,这里我们借用 Castle 的文档 https://github.com/castleproject/Core/blob/master/docs/dynamicproxy-introduction.md 有兴趣的朋友可以自行查询

总结

说到这里,我们已经基本了解了 castle构建动态代理的基本方法,接下来我们来总结一下代理对象的构建方法。 先区分目标是类还是接口,类的代理方法要求关键字virtual,无参构造可以使用 CreateClassProxy,有参数可以先获取到原始对象,传入 CreateClassProxyWithTarget;
接口同,无原始对象 CreateInterfaceProxyWithoutTarget ,有原始对象 CreateInterfaceProxyWithTarget
代码太多有点枯燥,本文先到这边。

标签:Core,ISampleService,聊一聊,Extensions,var,Castle,Microsoft,SampleService
From: https://www.cnblogs.com/sexintercourse/p/17962871

相关文章

  • 聊一聊如何结合Microsoft.Extensions.DependenyInjection和Castle.Core
    聊一聊如何结合Microsoft.Extensions.DependenyInjection和Castle.Core 合集-聊一聊如何整合Microsoft默认的Ioc容器和Castle.Core(4) 1.聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(二)01-122.聊一聊如何结合Microsoft.Extensions.Depend......
  • 聊一聊 .NET高级调试 中必知的符号表
    一:背景1.讲故事在高级调试的旅行中,发现有不少人对符号表不是很清楚,其实简而言之符号表中记录着一些程序的生物特征,比如哪个地址是函数(签名信息),哪个地址是全局变量,静态变量,行号是多少,数据类型是什么等等,目的就是辅助我们可视化的调试,如果没有这些辅助我们看到的都是一些无意义的......
  • 聊一聊 .NET高级调试 中的一些内存术语
    一:背景1.讲故事在高级调试的旅程中,经常会有一些朋友问我什么是工作集(内存),什么是提交大小,什么是VirtualSize,什么是WorkingSet。。。截图如下:既然有很多朋友问,这些用口头也不怎么好描述,刚好上午有时间就系统的聊一下吧。二:内存术语解读1.VirtualSize是什么可能有些朋......
  • 聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(完结篇)
    前言书接上回,上回我们了解了castle代理的一些缺点,本文将开始操作整合Microsoft.Extension.Dependency和Castle,以让默认的容器可以支持拦截器我们将以进阶的形式逐步完善我们的封装,以实现一个更方便易用、普适、高性能的基础设施库。基础版还是先上代码,这是基础版本我们......
  • [转][C#][.net Core]
    中文提示:连接数据库过程中发生错误,检查服务器是否正常连接字符串是否正确,错误信息:Onlytheinvariantcultureissupportedinglobalization-invariantmode.Seehttps://aka.ms/GlobalizationInvariantModeformoreinformation.(Parameter'name')en-usisaninvalid......
  • Asp .Net Core 系列: 集成 Consul 实现 服务注册与健康检查
    目录什么是Consul?安装和运行ConsulAsp.NetCore如何集成Consul实现服务注册和健康检查Consul.AspNetCore中的AddConsul和AddConsulServiceRegistration方法究竟做了什么?AddConsul方法AddConsulServiceRegistration方法配置Consul检查服务封装成扩展效果什么是C......
  • 聊一聊如何整合Microsoft.Extensions.DependencyInjection和Castle.Core(三)
    前言今天的第三篇,感觉没啥人看呀,难道没有兄弟跟我有同样的整合需求吗???手动,本文会简短一些,介绍下CastleCore作为代理库的一些缺点甚至是硬伤异步支持先上代码///<summary>///异常捕获、日志记录和耗时监控拦截器2024-1-1221:28:22///</summary>publicclassCatch......
  • netcore webpi 通过signalr 给vue项目推送消息
     最近项目上需要做个服务给前端推消息,首先就想到了signalr,关于signalr详情可以参考微软官方文档(ASP.NETCoreSignalR概述|MicrosoftLearn),微软现在也有使用教程(ASP.NETCoreSignalR入门|MicrosoftLearn)微软教程是通过使用库管理器(LibMan)从unpkg 获取客户端库,如......
  • .NET Core MemoryCache缓存批量获取Key或者删除
    .NetCore下使用缓存,除了大家耳熟能详的Redis做分布式缓存外,本地内存缓存也会一起结合来使用,它存取更快,使我们的应用达到极致性能要求。这也是我们经常提到的3级或者4级缓存,每一层都有自己的使用场景,优缺点,结合业务特点来选择合适的才是王道。这里我们就使用Net原生的Microsoft......
  • 无涯教程-Redis - ZSCORE 命令函数
    RedisZSCORE命令返回键排序后的元素的得分,如果元素不存在于排序集中,或者键不存在,则返回nil。ZSCORE-返回值返回元素的分数值。ZSCORE-语法以下是RedisZSCORE命令的基本语法。redis127.0.0.1:6379>ZSCOREkeymemberZSCORE-示例redis127.0.0.1:6379>ZADDm......