开源跨平台的.NET Core,还没上车的赶紧的,来不及解释了……
本系列文章,主要分享一些.NET Core比较优秀的社区资料和微软官方资料。我进行了知识点归类,让大家可以更清晰的学习.NET Core。
首先感谢资料原作者的贡献。
介绍.NET历史、开源之路、基础、路由、依赖注入DI、HttpContext、cookie|session、HttpClient、gRPC、单元测试、发布部署等等。
介绍.NET工程化、AOP、异常处理、缓存、日志、响应优化、上传下载、健康检查、后台任务、认证和授权、安全性(Https、CORS、CSRF)、EF Core 等等
介绍.NET跨平台的包袱与演变、.NET运行机制、性能分析方案;架构相关知识(设计原则、设计模式、DDD、微服务、中台等);.NET相关的微服务开发框架、微服务技术、云原生(docker、k8s)等
推荐资料:.NET开源github资源汇总(awesome-dotnet-core)
这是第一篇,知识点如图:
.NET 简介
#、.NET 开源之路
认识.NET Core(结构体系、特点、构成体系、编译器等)
2014.11月 .NET Core 项目启动,2016.06月 .NET Core 1.0 发布
.NET Core 3.0 新特性:支持 Windows 桌面应用(windows only)
微软将此新版本命名为.NET 5.0而不是.NET Core 4.0的原因有两个:
#、跳过版本号4.x,以避免与.NET Framework 4.x混淆。
#、从名称中删除了“ Core”,以强调这是.NET未来的主要实现。与.NET Core或.NET Framework相比,.NET 5.0支持更多类型的应用程序和平台。
ASP.NET Core 5.0基于.NET 5.0,但保留名称“ Core”以避免将其与ASP.NET MVC 5混淆。同样,Entity Framework Core 5.0保留名称“ Core”以避免将其与Entity Framework 5和6混淆。
值得注意的是,.NET 5并没有计划支持ASP.NET Web Form和Windows工作流(WF),因此.NET 5并不能完全代替.NET Framework。(更多 .NET5 功能)
.NET Core Roadmap
长期支持 LTS(Long-term Support)是怎样的一种支持方式
微软对 .NET Core 的长期支持策略有两种支持的时长:
#、某个 release 版本发布之后三年;
#、后续替代此 release 的另一个新的 release 发布之后一年
[翻译] .NET 官宣跨平台 UI 框架 MAUI (.NET 6)
微软停止更新 .NET Standard,.NET 5 取而代之
#、用于在 .NET Framework 和所有其他平台之间共享代码,使用 netstandard2.0
#、用于在 Mono,Xamarin 和 .NET Core 3.x 之间共享代码,使用 netstandard2.1
#、向后共享代码,使用net5.0
.NET 6 正式发布(LTS、性能、热重载、WebAssembly AOT 编译等)
#、.NET Core提供的特性
1.免费和最宽松的开源协议
.NET Core从属于.NET基金会,由微软进行官方支持。使用最宽松的MIT和Apache 2开源协议,文档协议遵循CC-BY。这将允许任何人任何组织和企业任意处置,包括使用,复制,修改,合并,发表,分发,再授权,或者销售。唯一的限制是,软件中必须包含上述版权和许可提示,后者协议将会除了为用户提供版权许可之外,还有专利许可,并且授权是免费,无排他性的(任何个人和企业都能获得授权)并且永久不可撤销,用户使用.NET Core完全不用担心收费问题,你可以很*的部署在任何地方.
2.轻量级、跨平台
3.组件化、模块化、IOC+Nuget、中间件
4.高性能
5.统一了MVC和WebAPI编程模型
a) 比如:ASP.NET Core 中MVC 和Web API 直接或间接继承同一个基类 ControllerBase,提供可使用的API也一致化
b) 比如:旧ASP.NET时代,写全局filter需要针对MVC 和Web API 分别编写代码,但在ASP.NET Core,直接使用一套中间件代码即可
6.可测试性
7.微服务、容器化支持
8.标准化 .NET API 规范- .NET STANDARD
#、迁移到.NET Core
目前市面上还存在很多传统 .NET 旧项目,我们需要根据公司情况决定是否升级到.NET Core。
如果需要进行旧项目升级的,可以参考文章:《.NET项目迁移到.NET Core操作指南》
VS和.NET Core安装
Vistual Studio
把.net Core 项目迁移到VS2019 for MAC(无需改一行代码)
VS 使用技巧
调试
.Net、C# 逆向反编译四大工具利器(dnSPY、ILSPY、Net Reflector、doPeek)
怎么直接在VS2017/2019按F12进行反编译查看源代码?
Visual Studio 2017中使用SourceLink调试Nuget包源码(SourceLink方式)
Visual Studio 2017调试开源项目代码(下载源代码文件方式)
使用.NET 6开发minimal api以及依赖注入的实现、VS2022热重载和自动反编译功能的演示
VS Code 开发.NET Core
.NET Core SDK
安装 .NET Core Runtime 和.NET Core SDK
Linux/MacOS 安装 .NET Core SDK 命令
如何删除 .NET Core 过时的运行时和 SDK (dotnet-core-uninstall)
指定.NET版本
Dotnet Core使用特定的SDK&Runtime版本(global.json)
【微软官方文档】ASP.NET Core *.* 各版本新特性
使用 Visual Studio 2019 批量添加代码文件头
基础
术语:
使用cmd命令行(.NET Core CLI)来启动ASP.NET Core 应用程序的多个实例
.NET Core 运行程序注意事项(dotnet dll 与 dotnet run)
core api 支持情况
ASP.NET Core 端口配置
.NET Core项目解读launchSettings.json(启动文件)
.NET Core 应用启动
ASP.NET Core 中 Startup 区分多个环境(IWebHostEnvironment)
ASP.NET Core 2.0 服务是如何加载并运行的, Kestrel、配置与环境
ASP.NET Core 中使用多个环境(开发、预发布、生产)- 调试默认为:Development;发布后默认为 Production
发布 asp.net core 时如何修改 ASPNETCORE_ENVIRONMENT 环境变量
ASP.NET Core 返回类型ActionResult|ActionResult<T>|Dto
ASP.NET Core 动作结果(ActionResult)
ASP.NET Core 中控制器操作的多路径返回类型(IActionResult)
在.Net Core 3.0中尝试新的System.Text.Json API
C#常见的文件路径Api(运行路径BaseDirectory、启动路径CurrentDirectory、程序集路径)--看评论3
配置
ASP.NET Core 中的配置(dotnet run变量、json、xml、环境变量、内存变量等)
在 .NET Core 中使用 ViewConfig 中间件调试配置
ASP.NET Core 中IOptions、IOptionsMonitor以及IOptionsSnapshot
ASP.NET Core 中修改配置不重启自动生效(ReadOnChange参数、IOptionsMonitor对象)
.Net Core 自定义配置源从远程API读取配置(ConfigurationProvider)
路由、模型绑定
ASP.NET Core WebAPI中,Controller标注 [ApiController] 特性,其路由只能使用[route]特性方式
ASP.NET Core MVC 构建可读性更高的ASP.NET Core 路由
ASP.NET Core 3.x 为什么采用新的 Endpoint Routing 路由系统
ASP.NET Core 中的自定义模型绑定(IModelBinder)
使用Dynamic来直接操作API请求的数据(JTextAccessor)
ASP.NET Core API默认支持的InputFormatters:application/json-patch+json、application/json、text/json、application/*+json
ASP.NET Core API默认支持的OutputFormatters:text/plain、application/json、text/json、application/*+json
ASP.NET Core Web API 入参解析InputFormatter
ASP.NET Core Web API 对输入流stream的支持
ASP.Net Core Web Api中异步视频流的IOutputFormatter
ASP.NET Core 实现支持自定义 Content-Type
InputFormatter 用来解析请求 Body 的数据,将请求参数映射到强类型的 model,Request Body => Value
OutputFormatter 用来将强类型的数据序列化成响应输出,Value => Response Body
Formatter 需要指定支持的 MediaType,可以理解为请求类型,体现在请求头上,对于 InputFormatter 对应的就是 Content-Type ,对于 OutputFormatter 对应的是 Accept,asp.net core 会根据请求信息来选择注册的 formatter。
控制反转、依赖注入
什么是控制反转,和依赖注入:
依赖倒置原则(Dependence inversion principle,DIP):软件设计原则,要依赖于抽象,不要依赖具体实现。
控制反转(Inversion of Control,IoC):IOC是一种实现DIP原则的模式。平常我们需要一个类对象的时候需要new出来,而现在我们把new一个类对象的工作交给了IOC容器,当我们需要一个类对象的时候直接向IOC容器要,就可以了,这个就是控制反转。(控制权交个了IOC容器)
依赖注入(Dependency Injection,DI):DI是实现IOC的一种方式。当我需要一个类对象,IOC容器给我们这个类对象的过程其实就是依赖注入,依赖注入有构造函数注入和属性注入。
官方推荐通过构造函数。这也是所谓的显式依赖。Asp.Net Core 的标准依赖注入容器不支持属性注入。(可以使用autofac或者其他来实现属性注入)
可以参考 Abp 框架,设计三个全局注入接口,来实现自动化注入:ISingletonDependency 和 ITransientDependency 、 IScopedDependency ( 单例、瞬时、范围)。
如何实现一个接口注入多个实现类?
ASP.NET Core默认注入方式下如何注入多个实现(多种方式)
案例1:使用nlog时,想根据需要使用不同的配置文件 Nlog.config 写日志时
案例2:使用分布式缓存 IDistributedCache 时,想根据需要在一个项目中同时使用redis和sqlserver
ASP.NET Core 中多个接口对应同一个实现的正确姿势
[OSharp]使用 IServiceProvider.GetService<T>() 实现按需注入,优化性能
在WPF中使用.NET Core 3.0依赖项注入和服务提供程序
.NetCore之依赖注入作用域和对象释放(根容器、请求容器)
.NetCore 中IServiceProvider的 GetService()和GetRequiredService()之间的区别
- GetService- 如果服务未注册,则返回null
- GetRequiredService- 如果服务未注册,则抛出一个Exception异常
#、ASP.NET Core 结合 Autofac 的使用
Asp.Net Core 2.0 之旅---AutoFacIOC容器的使用教程(批量注入)
Asp.Net Core 2.0 之旅---AutoFac仓储泛型的依赖注入(泛型注入)
ASP.NET Core 技巧之伪属性注入(属性注入会造成类型的依赖关系隐藏,测试不友好等)
ASP.NET Core 2.0中使用Autofac实现属性注入的代码片段
public IServiceProvider ConfigureServices(IServiceCollection services) { // 第一步:替换系统默认Controller创建器(否则Controller下面无法使用属性注入) // 在 services.AddMvc() 之前 services.Replace(ServiceDescriptor.Transient<IControllerActivator, ServiceBasedControllerActivator>()); services.AddMvc(); var builder = new ContainerBuilder(); // 第二步:找到所有Controller的类型 // 通过Autofac对Controller类型进行属性注册 PropertiesAutowired() var assembly = this.GetType().GetTypeInfo().Assembly; var manager = new ApplicationPartManager(); manager.ApplicationParts.Add(new AssemblyPart(assembly)); manager.FeatureProviders.Add(new ControllerFeatureProvider()); var feature = new ControllerFeature(); manager.PopulateFeature(feature); builder.RegisterTypes(feature.Controllers.Select(ti => ti.AsType()).ToArray()).PropertiesAutowired(); // 第三步:配置 ContainerBuilder,返回 IServiceProvider builder.Populate(services); return new AutofacServiceProvider(builder.Build()); }
浅谈.Net Core 3.1中使用Autofac替换自带的DI容器
在 .Net Core2 中一般是把 Startup 的 ConfigureServices 方法返回值类型改为IServiceProvider,然后通过构建Autofac容器并注入服务后返回。
在 .Net Core3.0之后,集成方式做了部分调整
#、构造函数注入&属性注入
描述来源于Abp.io中文文档:查看详情
构造方法注入
是将依赖项注入类的首选方式.这样,除非提供了所有构造方法注入的依赖项,否则无法构造类.因此,该类明确的声明了它必需的服务.
属性注入
public class MyService : ITransientDependency
{
public ILogger<MyService> Logger { get; set; }
public MyService()
{
Logger = NullLogger<MyService>.Instance;
}
}
对于属性注入依赖项,使用公开的setter声明公共属性.这允许DI框架在创建类之后设置它.
属性注入依赖项通常被视为可选依赖项.这意味着没有它们,服务也可以正常工作.Logger就是这样的依赖项,MyService可以继续工作而无需日志记录.
为了使依赖项成为可选的,我们通常会为依赖项设置默认/后备(fallback)值.在此示例中,NullLogger用作后备.因此,如果DI框架或你在创建MyService后未设置Logger属性,则MyService依然可以工作但不写日志.
属性注入的一个限制是你不能在构造函数中使用依赖项,因为它是在对象构造之后设置的.
当你想要设计一个默认注入了一些公共服务的基类时,属性注入也很有用.如果你打算使用构造方法注入,那么所有派生类也应该将依赖的服务注入到它们自己的构造方法中,这使得开发更加困难.但是,对于非可选服务使用属性注入要非常小心,因为它使得类的要求难以清楚地看到.
ASP.NET Core WebAPI
API接口设计最佳实践(token,协议规范,路径规范,版本管理,调用门槛,返回规范,安全性,幂等性)
创建ASP.NET Core Web API (ControllerBase、参数绑定源)
版本控制
ASP.Net Core WebAPI 几种版本控制对比(nuget:Microsoft.AspNetCore.Mvc.Versioning)
ASP.NET Core 构建带有版本控制的 API 接口(结合SwaggerUI)
ASP.NET Core AutoWrapper 自定义响应输出
API调试工具
API集成管理平台YAPI的搭建和使用 (具有多人协作的功能) (体验地址)
ASP.NET Core:MVC 与 Razor Pages
ASP.NET Core MVC 静态文件目录配置与访问授权
ASP.NET Core 中的特殊视图文件(_Layout.cshtml、_ViewStart.cshtml、_ViewImports.cshtml)
ASP.NET Core 3.1 Razor 视图预编译、动态编译
新的 Razor 机制
ASP.NET Core 中的 Razor 页面介绍(OnGet、OnPost、单页多Handler方式)
ASP.NET Core 中 Razor 页面的IPageFilter
ASP.NET Core 中 Razor 页面的路由和应用约定
ASP.NET Core Razor 配置:预编译,动态编译,混合编译
WebForm & MVC & Razor Pages
[译]ASP.Net Core 2.0中的Razor Page不是WebForm
ASP.NET Core Razor页面简化了 ASP.NET MVC 应用程序
HttpContext
ASP.NET Core 中访问 HttpContext 的方法
ASP.NET Core 中通过IHttpContextAccessor实现公用静态HttpContext
状态管理
常见方式:Cookie、Session、TempData、查询字符串、HttpContext.Items、缓存、依赖关系注入
#、session
ASP.NET Core 在通用数据保护条例规则下使用 session
#、cookie
Cookie 的 SameSite 属性(注意http>>https重定向跨域导致的cookie丢失问题)
ASP.NET Core SameSite 设置引起 Cookie 在 QQ 浏览器中不起作用
[github]ASP.NET Core CookieManager
通信
#、HttpClient
传统.NET HttpClient坑
ASP.NET Core HttpClient的各种用法、生命周期管理
DotNetCore 使用Http请求及基于 Polly 的处理故障
DotNetCore 中 HttpClientFactory 类源码分析
#、RPC
Grpc
.NET Core 中的 gRPC 客户端工厂集成(依赖注入)
两个gRPC的C#库:grpc-dotnet vs Grpc.Core
Grpc调试:AspNetCore.Grpc.Swagger 由微软提供(.NET5.0版本)--(github issue)
支持使用Restful API方式调用Grpc方法:GrpcJsonTranscoder
[github]基于gRPC的实时网络引擎:MagicOnion
DotNetty
[github]Azure开源的网络通信框架DotNetty
#、SignalR
ASP.NET Core基于SignalR实现消息推送实战演练
发布部署
nginx
asp.net core 只有发布之后才能在IIS上部署访问(而asp.net 程序 是可以直接指定到源代码目录访问)
.Net Core 跨平台:一个简单程序的多平台(windows、Linux、osx)发布
.NET Core RID 目录 (参数:-r|--runtime)
.NET Core 目标框架 (参数:-f|--framework)
dotnet publish 发布的文件中包含pdb文件,不论模式是Debug还是Release。可以通过配置:
<PropertyGroup Condition=" \'$(Configuration)\' == \'Release\' ">
<DebugType>None</DebugType>
<DebugSymbols>false</DebugSymbols>
……
</PropertyGroup>
--self-contained 自包含参数。将.NET Core运行时及.NET Core类库随应用一起打包,这样可以完全避免老项目在系统.NET Core运行时升级时,带来莫名异常的问题
发布 .NET 5 带运行时单文件应用时优化文件体积的方法(.pubxml)
IIS上部署.NET Core应用
第一步:安装 ASPNetCoreModule2 模块 (ASPNetCoreModule和ASPNetCoreModuleV2之间有什么区别?)
第二步:IIS部署.Net5全流程
在Linux上使用 pm2 守护你的 .NET Core 应用程序--(pm2 github starts 31.1k)
在Linux上使用Nginx + supervisor部署ASP.NET Core程序--(supervisor github starts 5.8k)
在Docker上部署自动更新ssl证书的nginx + .NET Core
配置 ASP.NET Core 以使用代理服务器和负载均衡器
使用 Nginx 在 Linux 上托管 ASP.NET Core
使用 Apache 在 Linux 上托管 ASP.NET Core
单元测试
.NET Core 和 .NET Standard 单元测试最佳做法
使用 dotnet test 和 xUnit 在 .NET Core 中进行 C# 单元测试
使用 dotnet test 和 NUnit 在 .NET Core 中进行 C# 单元测试
使用 dotnet test 和 MSTest 在 .NET Core 中进行 C# 单元测试
使用 dotnet test --filter 进行选择性单元测试
视频教程
ASP.NET Core 3.0 入门视频 -- solenovex
一些坑
时间相关
c#:细说时区、DateTime和DateTimeOffset在国际化中的应用
DateTimeOffset(推荐)
C#中DateTime的缺陷与代替品DateTimeOffset
DateTime(旧系统)
dotnet core windows和linux的时区处理 (开源库:nodatime)
Blazor
Blazor托管模型:在客户端模型中,Blazor在浏览器内部的WebAssembly(WASM)上运行,在服务器端模型中,Blazor在服务器上运行,并通过Signal-R将HTML传输到客户端
==============================================================================
over,谢谢查阅,觉得文章对你有收获,请多帮推荐。欢迎向我提供更好的资料信息。