kitlau

kitlau's blog

All Posts


还在背依赖注入的概念?不如自己写一个依赖注入框架

本篇博客以依赖注入(DI)框架为例,详细介绍了如何从零开始构建一个DI框架。首先,博客讲解了DI的基本概念,包括服务、服务描述符和服务提供者。接着,通过创建一个KServiceCollection类,实现了DI的基础功能。然后,通过使用KServiceCollection类创建一个KServiceProvider类,实现了服务的获取和注入。在此基础上,博客进一步讲解了如何通过创建单例和瞬态服务,实现不同生命周期的管理。最后,通过在控制台项目中创建新服务和重写Program.cs文件,进行了DI框架的测试。 此篇博客深入浅出地讲解了DI框架的构建过程,旨在帮助读者更好地理解DI的概念和应用。同时,博客也提出了一些有趣的问题,比如如何解决null值检查的问题,如何约束TImplement类型必须实现TService接口,如何实现Remove功能等,以引发读者的思考。而这些问题的解决,将是读者自己完成DI框架的关键步骤。 此外,博客也强调了编程学习的方式,批评了应试教育的学习方式,并指出这种方式对开发者创造力的扼杀。博客希望读者能够通过动手实践,真正理解和掌握编程知识。那么,你是否已经准备好,开始自己的DI框架构建之旅呢?--GPT 4

.NET DependencyInjection

异步的原理是什么?C# 如何基于状态机实现异步?

本篇博客详细解析了异步的原理以及C#如何基于状态机实现异步。首先,文章介绍了C#中的异步方法,包括其结构、状态机的工作方式以及如何通过IAsyncStateMachine接口实现异步。然后,博客详细讲解了状态机的MoveNext()方法,包括它的工作原理,如何在异步方法第一次调用时被调用,以及每次恢复执行时都被调用一次。文章还解释了在await表达式时,有两种可能,await的异步操作尚未完成,或者已经完成。最后,博客总结了MoveNext()方法的工作流程,并通过流程图形象地展示了异步方法的执行过程。那么,为什么“尚未启动”和“正在执行”状态用同一个值表示?这篇博客是否能帮助你理解C#异步的实现呢?--GPT 4

C#

什么是异步?异步就是多线程吗?异步就是 async、await 吗?

这篇博客主要探讨了异步编程的一些基本概念和用法,包括异步方法的调用、async/await关键字的作用以及异步方法的执行顺序等。通过一系列的示例,我们可以看到异步方法在被调用时就会立即开始执行,而await关键字则是用来等待异步方法执行完成并获取返回结果。在调用异步方法和await这个异步方法返回的Task之间,我们还可以去做其他事情,比如再运行一个与之前的异步方法无关的异步方法。此外,这篇博客还介绍了如何在不使用async修饰的情况下编写异步方法,以及如何使用Task.WhenAll()来同时等待多个Task完成。最后,作者指出虽然这篇文章只讲了异步编程的一些表象,但已经足够用来进行开发,如果要深入理解异步编程的原理,还需要进一步的学习和实践。那么,你是否已经理解了这些异步编程的基本概念和用法呢?你是否已经准备好放心大胆地使用异步编程了呢?--GPT 4

C#

EF Core 何时、为何使用 IsUnicode 方法

这篇博客主要讨论了EF Core中`IsUnicode()`方法的使用时机和原因。首先,作者通过实验发现,`IsUnicode()`对MariaDB没有什么用,对MSSQL Server则会改变C# string类型的属性在数据库中的数据类型。当不使用`IsUnicode()`或配置为`IsUnicode(true)`时,生成的数据库表中对应string字段的数据类型为`nvarchar`,而配置`IsUnicode(false)`时则为`varchar`。因此,作者建议,当我们确定一个string类型的属性是ASCII安全的时候,即这个属性的值只会包含数字、英文字母和英文符号时,可以为它配置`IsUnicode(false)`,这样它在数据库中就是`varchar`类型。但如果你不确定,最好还是保持默认。此外,作者还分享了他的一些经验,例如对于ASCII安全的字符串来说,`nvarchar`要比`varchar`多占1倍的存储空间,而且还要考虑性能的影响。在博客的最后,作者介绍了EF Core 6中引入的新特性:Unicode Attribute,并总结了软件开发中需要注意的一些问题。--GPT 4

C# EF Core

彻底理解 ASCII Unicode UTF-8 UTF-32 是什么以及区别与联系

本篇博客详细介绍了ASCII,Unicode,UTF-8和UTF-32的定义,起源以及它们之间的区别和联系。博客首先解释了ASCII的编码过程,然后介绍了由于ASCII无法表示除英文字符以外的其他文字和符号,Unicode标准的出现。Unicode包含100多种语言中的超过10万个独特字符。接着,博客详细描述了Unicode和ASCII的区别,以及如何将字素映射到编码点。接下来,博客讨论了UTF-8和UTF-32这两种编码策略,以及它们与ASCII的区别。UTF-32将每个编码点的值编码为4个字节,而UTF-8则将每个编码点编码为8-32位,即1到4个字节。最后,博客总结了在Unicode中,一个字素不等于一个编码点,也不等于一个字节,并且我们必须知道原始的编码规则才能将字节解码为字素。在阅读完整篇博客后,你是否能理解为什么在不同的编程语言中,相同的字符串在长度上可能会有所不同?你是否了解在何种情况下应使用不可感知Unicode的函数,可感知Unicode的函数和可感知字素的函数?--GPT 4


EF Core 动态构建表达式树简化 DDD 值对象的比较

本篇博客探讨了如何使用EF Core动态构建表达式树简化DDD值对象的比较。首先,文章讲述了如何在EF Core中使用值对象,以及遇到的问题。接着,文章提出了使用动态构建表达式树的查询作为解决方案,并详细解释了如何实现这个解决方案,包括创建一个名为`ValueObjectEqualHelper`的静态类,以及如何使用这个类中的`CheckEqual<T, TProperty>`静态方法。最后,博客展示了如何使用这个方法,并展示了生成的SQL脚本和输出结果。这个方法是否能够解决你在EF Core中使用值对象时遇到的问题呢?对于动态构建表达式树,你有什么其他的想法和建议吗?--GPT 4

.NET EF Core

EF Core 动态构建表达式树为所有实体设置软删除的查询过滤器

这篇博客文章介绍了如何在EF Core中动态构建表达式树,实现对所有实体设置软删除的查询过滤器。首先,文章通过一个简单的实体类和一个实体配置类来演示如何在EF Core中设置查询过滤器。然后,文章提出了一个问题:如果项目中有大量的实体,每个实体都进行一次查询过滤器的配置将会非常麻烦。为了解决这个问题,文章引入了动态构建表达式树的方法。通过动态构建表达式树,我们可以在应用程序启动时,遍历所有的实体类型,对有软删除标志的实体动态设置查询过滤器。文章还演示了如何在查询时忽略查询过滤器,以及如何简化动态构建表达式树的代码。最后,文章预告了下一篇博客的主题,将会介绍如何使用动态构建表达式树来简化和语义化领域驱动设计中值对象的比较。这篇博客对于那些在EF Core中使用查询过滤器,或者需要动态构建表达式树的开发人员来说,将会有很大的帮助。那么,你是否已经想象出如何在你的项目中应用这些方法了呢?--GPT 4

.NET EF Core

手把手构建 C# 表达式树

本篇博客详细解析了如何构建C#表达式树。首先,博客介绍了为何要构建表达式树,并以构建`p => p.Age > 18`这个lambda表达式为例,详细解释了构建过程。在构建过程中,首先创建了Person类,然后将表达式画成一个简单的表达式树,然后依次构建了树的各个节点,包括参数表达式、成员表达式、常量表达式、二元运算符表达式等。最后,将所有构建好的表达式组合成一个完整的lambda表达式。此外,博客还展示了如何使用这个构建好的表达式树,并解释了手动编译表达式的必要性。最后,博客预告了接下来会写两篇关于如何将表达式树应用在EF Core的文章,让读者对此产生了期待。那么,你是否已经理解了如何构建表达式树呢?你是否也对如何将其应用在EF Core中充满了好奇呢?--GPT 4

.NET

如何使用 CSharp 表达式树?

本篇博客详细介绍了如何使用 CSharp 表达式树,通过一个实际的例子展示了如何手动构建表达式树。博文首先解释了表达式树的概念,并通过 C# 中的语法树为读者提供了直观的理解。接着,博文对 .NET 中的 `Expression<TDelegate>` 类型进行了详细的解析,并通过代码示例展示了如何从 lambda 表达式生成 `Expression<TDelegate>` 类型的变量,以及如何将其编译成 `TDelegate` 类型的委托对象。然后,博文通过一个实际的例子,详细地介绍了如何手动构建表达式树,包括如何构建叶子节点和根节点,以及如何编译和调用表达式树。最后,博文提到了表达式树在简化值对象比较中的应用,并给出了相关的参考文档链接。那么,表达式树是否真的能够避免硬编码,从而使代码更易于维护呢?阅读全文,你将得到答案。--GPT 4

C#

【译】数据是如何存储在 SQL 数据库中

本篇博客主要讲述了数据在 SQL 数据库中的存储方式。首先,虽然表中的数据在逻辑上以行和列的格式存储,但在物理上,它以数据页的形式存储,数据页是 SQL Server 中数据存储的基本单位。其次,SQL Server 中的表数据实际上存储在一个类似树的结构中,这种树状结构被称为 B-Tree、index B-Tree 或 Clustered index structure。数据实际上存储在一系列数据页中,这些数据页的树形结构如下所示。在树底部的节点称为数据页或树的叶节点,正是这些叶节点包含我们的表数据。每个数据页的大小为 8KB,这意味着每个数据页中存储的行数实际上取决于每行的大小。位于树顶部的节点称为根节点,根节点和叶节点之间的节点称为 intermediate levels。根节点和中间层节点包含索引行,而叶节点包含实际的数据行。每个索引行包含一个键和一个指向 B 树中的中间层节点或叶节点中的数据行的指针。这个树状结构有一系列的指针,可以帮助数据库引擎快速找到数据。最后,文章简要介绍了 SQL Server 是如何通过 ID 找到一个数据行的。这篇博客对于理解 SQL 数据库的数据存储方式非常有帮助。你觉得 SQL Server 的这种数据存储方式有什么优点和缺点吗?--GPT 4

DB