C#
文章平均质量分 91
猰貐的新时代
一个毕业于浙大的博客新手,目前就职于腾讯的全栈领域优质创作者,坚信越努力越幸运,请多关照!
展开
-
实现任意的拦截器注册方式
ConditionalInterceptorProvider利用构造函数注入的IOptions<ConditionalInterceptorProviderOptions>得到这组映射关系,CanIntercept方法利用这组关系的匹配条件确定指定的方法是否应该被拦截,另一个GetInterceptors方法则利用匹配的工厂来创建返回的这组Sortable<InvokeDelegate>对象。在提供具体实现之前,我们先来体验一下由它达成的编程模型。三、实现一种“万能”的拦截器注册方式。原创 2023-12-23 17:45:13 · 132 阅读 · 0 评论 -
如何在ASP.NET Core应用中实现与第三方IoC/DI框架的整合?
当MyServiceProvider的Dispose方法被调用的时候,提供的这些服务实例的Dispose方法会被调用。但是对于我们的MyServiceProvider对象来说,当调用它的GetService方法试图获取ServiceScopeFactory对象的时候,获取的实际上是被封装的那个SerivceProvider关联的ServiceScopeFactory,那么很自然创建的“子ServiceProvider”也与MyServiceProvider没有什么关系。三、如何解决这个问题?原创 2023-06-16 14:07:53 · 1003 阅读 · 0 评论 -
几个Caller-特性的妙用
如果指定的是一个变量(或者参数),捕获到的就是变量名。System.Runtime.CompilerServices命名空间下有4个以“Caller”为前缀命名的Attribute,我们可以将它标注到方法参数上自动获取当前调用上下文的信息,比如当前的方法名、某个参数的表达式、当前源文件的路径,以及当前代码在源文件中的行号。如果我们按照如上的方式调用Invoker的构造函数,并将Null作为参数,此时会抛出如下的异常,可以看到抛出的ArgumentNullException异常被赋予了正确的参数名。原创 2023-06-16 07:02:12 · 209 阅读 · 0 评论 -
如何实现Http请求报头的自动转发之设计
我们说过,所有的报头具有两个来源,其中一个来源于当前接收的请求,但是并不是请求中携带的所有报头都需要转发,所以我们需要利用如下这个HeaderForwarderOptions类型来配置转发的报头名称。HeaderForwarder组件不仅能够从当前接收请求提取指定的HTTP报头,并自动将其添加到任何一个通过HttpClient发出的请求中,它同时也提供了一种基于Context/ContextScope的编程模式是我们可以很方便地将任何报头添加到指定范围内的所有由HttpClient发出的请求中。原创 2023-06-15 07:32:26 · 430 阅读 · 0 评论 -
.NET的基元类型包括哪些?Unmanaged和Blittable类型又是什么?
从该方法的实现和CorElementType的枚举成员也可以看出,枚举值2-13,外加CorElementType.I(IntPtr)和CorElementType.U(UIntPtr)这14个类型属于基元类型的范畴,这与上面的列表是一致的。在讨论.NET的类型系统的时候,我们经常提到“基元类型(Primitive Type)”的概念,我发现很多人并没有真正理解基元类型就究竟包含哪些(比如很多人觉得字符串是基元类型)。顾名思义,Unmanaged类型可以理解不涉及托管对象引用的值类型。原创 2023-06-15 07:25:19 · 1142 阅读 · 0 评论 -
如何计算一个实例占用多少内存?
二、Marshal.SizeOf方法我们都知道CPU和内存是程序最为重要的两类指标,那么有多少人真正想过这个问题:一个类型(值类型或者引用类型)的实例在内存中究竟占多少字节?我们很多人都回答不上来。其实C#提供了一些用于计算大小的操作符和API,但是它们都不能完全解决我刚才提出的问题。本文提供了一种计算值类型和引用类型实例所占内存字节数量的方法。一、sizeof操作符sizeof操作用来确定某个类型对应实例所占用的字节数,但是它只能应用在类型上。原创 2023-06-13 07:49:36 · 418 阅读 · 0 评论 -
如何将一个实例的内存二进制内容读出来?
在如下所示的代码片段中,我们在输出FoobarClass对象的内存字节序列后,我们进一步获得了FoobarClass类型的TypeHandle对象,该对象的Value属性返回的就是方法表地址。是6(采用小端字节序)。如下面的代码片段所示,我们创建了上面定义的Foobar对象,在将其内存字节打印出来之前,我们先将其GetHashCode方法返回的哈希码打印来。在了解了Object Header的字节布局后,我们利用我们定义的方法将对象的Object Header的内容读取出来,看看它的内容是否与描述的一致。原创 2023-06-13 07:42:28 · 251 阅读 · 0 评论 -
动态方法拦截(AOP)的N种解决方案
在实现的Invoke方法中,它在调用封装对象的同名方法之前率先执行了拦截操作。AOP的本质是方法拦截(将针对目标方法调用劫持下来,进而执行执行的操作),置于方法拦截的实现方案,不外乎两种代码注入类型,即编译时的静态注入和运行时的动态注入,本篇文章列出了几种常用的动态注入方案。以下面的代码片段为例,我们需要拦截定义在Foobar中的虚方法Invoke,我们可以生成如下这个派生与Foobar的Foobar的FoobarProxy类型,在重写的Invoke方法中,我们在调用基类同名方法之前,率先执行拦截操作。原创 2023-06-12 08:19:36 · 1035 阅读 · 0 评论 -
如何兼顾性能+实时性处理缓冲数据?
在构造函数中,我们调用了ChangeToken的静态方法OnChange将数据处理操作绑定到创建的BatchChangeToken对象上,并确保每次发送“数据处理”后将重新创建的BatchChangeToken对象赋值到_changeToken字段上,因为Add放到需要调用它的Increase增加计数。由于提供的数组来源于对象池,所以并不能保证每个数据元素都承载了有效的数据,实现的迭代器和返回数量的Count属性对此作了相应的处理。为了避免缓冲数据带来的内存分配,我们使用了一个单独的。原创 2023-06-12 08:08:47 · 182 阅读 · 0 评论 -
兼顾性能+实时性处理缓冲数据解决方案
在构造函数中,我们调用了ChangeToken的静态方法OnChange将数据处理操作绑定到创建的BatchChangeToken对象上,并确保每次发送“数据处理”后将重新创建的BatchChangeToken对象赋值到_changeToken字段上,因为Add放到需要调用它的Increase增加计数。由于提供的数组来源于对象池,所以并不能保证每个数据元素都承载了有效的数据,实现的迭代器和返回数量的Count属性对此作了相应的处理。为了避免缓冲数据带来的内存分配,我们使用了一个单独的。原创 2023-06-04 08:42:16 · 294 阅读 · 0 评论 -
用最少的代码模拟gRPC四种消息交换模式
作为模拟,客户端会携带一个名字列表(“foo,bar,baz,qux”),服务端以流的形式针对每个名字回复一个问候消息,具体的实现体现在针对请求路径“/serverstream”的路由处理方法HandleServerStreamCallAsync上。MessageContent将代表ProtoBuf消息的IMessage对象作为主体内容,在重写的SerializeToStreamAsync,我们调用上面定义的WriteMessageAsync扩展方法将指定的IMessage对象写入输出流中。原创 2023-05-29 10:36:52 · 805 阅读 · 0 评论