|
| 1 | +# .NET 每周分享第 30 期 |
| 2 | + |
| 3 | +## 卷首语 |
| 4 | + |
| 5 | +[为什么选择 .NET](https://devblogs.microsoft.com/dotnet/why-dotnet/) |
| 6 | + |
| 7 | + |
| 8 | + |
| 9 | +最近 `.NET` 团队发布了一篇文章,介绍了自从 `.NET` 开源以来,微软和社区为 `.NET` 的发展和壮大做出的各种努力和付出。这也是为什么我们要选择 `.NET` 的原因。 |
| 10 | + |
| 11 | +## 行业资讯 |
| 12 | + |
| 13 | +1、[.NET 语言更新策略](https://devblogs.microsoft.com/dotnet/update-to-the-dotnet-language-strategy/) |
| 14 | + |
| 15 | + |
| 16 | + |
| 17 | +在 `.NET` 平台上有三种编程语言可以运行,分别是 `C#`, `F#` 和 `Visual Basic` 三种语言,那么微软官方对三种语言的支持承若是怎样的呢? |
| 18 | + |
| 19 | +- C# 是广泛使用的编程语言:1)广泛和积极的创新;2)保持这门语言的内在精神;3)服务于最广大的开发者;4)最大程度保证兼容;5)保持支持。 |
| 20 | +- F# 用来探索函数式语言的可能性:1)保持语言的统治性和前瞻能力;2)依赖社区提供重要的库,开发工具和工作场景;3)支持 .NET 平台的其他更新和保持互操作性;4)保持低入门槛。 |
| 21 | +- VB 是兼容已经存在的代码:1)保持一个直接和可操作的编程语言;2)稳定的设计;3)保持可接受的方法和语法;4)持续提高 VS 中的体验;5)所有工作都在 VB 核心中。 |
| 22 | + |
| 23 | +## 文章推荐 |
| 24 | + |
| 25 | +1、[组织你的 .NET 项目](https://www.jamesmichaelhickey.com/how-to-structure-your-dot-net-solutions-design-and-trade-offs/) |
| 26 | + |
| 27 | +如果你作为一个创业公司的 CTO,需要为自己的产品和服务开发一套服务,你会又很多问题需要考虑 |
| 28 | + |
| 29 | +**代码方面** |
| 30 | + |
| 31 | +- 单个解决方案 |
| 32 | +- 拆分多个项目 |
| 33 | + |
| 34 | +**部署方面** |
| 35 | + |
| 36 | +- 一次部署 |
| 37 | +- 使用负债均衡器部署多个服务 |
| 38 | +- 特定请求发送给特定的服务器 |
| 39 | +- 微服务部署 |
| 40 | + |
| 41 | +**通信** |
| 42 | + |
| 43 | +- 内存消息通信 |
| 44 | +- API 请求通信 |
| 45 | +- 消息队列 |
| 46 | + |
| 47 | +**数据库** |
| 48 | + |
| 49 | +- 单个数据库 |
| 50 | +- 多个数据库 |
| 51 | +- 数据库分片 |
| 52 | + |
| 53 | +这些选择都是基于业务的需求不停的演变,这篇文章介绍为什么需要选择这个措施,有哪些 `Trade-off`, 以及具体的例子。 |
| 54 | + |
| 55 | +2、[EventSource 学习](https://www.youtube.com/watch?v=yWpuUHXLhYg&ab_channel=CodeOpinion) |
| 56 | + |
| 57 | +Event Source 是广泛使用的持久化状态的工具, `Marten` 是 `.NET` 平台使用的的 `Event` 库,`Jermery Miller` 也是 `Marten` 是维护者。 |
| 58 | + |
| 59 | +3、[C# Web 安全开发建议](https://dev.to/bytehide/net-security-headers-a-senior-developers-guide-150d) |
| 60 | + |
| 61 | + |
| 62 | + |
| 63 | +我们都知道 Web 是不安全的,那么作为 `.NET` Web 开发工程师,需要在服务端做好这些防护工作。 |
| 64 | + |
| 65 | +1. X-XSS-Protection Header |
| 66 | + |
| 67 | +跨站脚本攻击是一件常见的的攻击手段,它可以通过在用户页面自动执行一些脚本就可以达到攻击的页面. `HTTP Header` 中的 `X-XSS-Proection` 可以阻止脚本执行 |
| 68 | + |
| 69 | +```csharp |
| 70 | +public void Configure(IApplicationBuilder app, IHostingEnvironment env) |
| 71 | +{ |
| 72 | + app.Use(async (context, next) => |
| 73 | + { |
| 74 | + context.Response.Header.Add("Content-Security-Policy", "default-src 'self';"); |
| 75 | + await next(); |
| 76 | + }); |
| 77 | + app.UseMvc(); |
| 78 | +} |
| 79 | +``` |
| 80 | + |
| 81 | +2. Content-Security-Policy Header |
| 82 | + CSP 允许你那些资源可以在浏览器中执行 |
| 83 | + |
| 84 | +```csharp |
| 85 | +public void Configure(IApplicationBuilder app, IHostingEnvironment env) |
| 86 | +{ |
| 87 | + app.Use(async (context, next) => |
| 88 | + { |
| 89 | + Context.Response.Header.Add("Content-Security-Policy", "default 'self';"); |
| 90 | + await next (); |
| 91 | + }); |
| 92 | +} |
| 93 | +``` |
| 94 | + |
| 95 | +3. X-Frame-Options Headers |
| 96 | + |
| 97 | +攻击者可以通过 `ClickJacking` 方式对 UI 进行重绘,这样可以误导用户错误点击,`X-Frame-Options` Header 可以限制这样的行为。 |
| 98 | + |
| 99 | +```csharp |
| 100 | +public void Configure(IApplicationBuilder app, IHostingEnvironment env) |
| 101 | +{ |
| 102 | + app.Use(async (context, next) => |
| 103 | + { |
| 104 | + context.Response.Header.Add("X-Frame-Options", "DENY"); |
| 105 | + await next(); |
| 106 | + }) |
| 107 | +} |
| 108 | +``` |
| 109 | + |
| 110 | +4. HSTS |
| 111 | + 我们都知道 `HTTP` 协议不安全,应该选择 `HTTPS` 版本,但是仍然有办法绕过 `HTTPS` 而是直接使用 `HTTP`。 `HSTS` 可以强制使用 `HTTPS` 协议。 |
| 112 | + |
| 113 | +```csharp |
| 114 | +public void Configure(IApplicationBuilder app, IHostingEnvironment env) |
| 115 | +{ |
| 116 | + app.UseHsts(); |
| 117 | +} |
| 118 | +``` |
| 119 | + |
| 120 | +4、[Powershell 入门系列教程](https://twitter.com/khalilApriday/status/1623920383979290624) |
| 121 | + |
| 122 | + |
| 123 | + |
| 124 | +这是一个 Powershell 学习资源的 twitter thread, 主要包含一下内容 |
| 125 | + |
| 126 | +- [自动化管理员任务](https://learn.microsoft.com/en-us/training/paths/powershell/) |
| 127 | +- [Powershell 大师课程](https://www.youtube.com/playlist?list=PLlVtbbG169nFq_hR7FcMYg32xsSAObuq8) |
| 128 | +- [Powershell IT 专业人员教程](https://kamilpro.com/powershell-for-it-professionals/) |
| 129 | +- [微软官方教程](https://learn.microsoft.com/en-us/shows/getting-started-with-microsoft-powershell/) |
| 130 | +- [PSkoans](https://github.com/vexx32/PSKoans) |
| 131 | +- [Powershell 7 训练课程](https://www.linkedin.com/learning/powershell-7-essential-training?src=aff-ref&trk=aff-ir_progid.8005_partid.259799_sid._adid.647232&clickid=yJLQBuWowxyNU3VyfNU4iUJJUkA3KoznK3IVVU0&mcid=6851962469594763264&irgwc=1) |
| 132 | + |
| 133 | +5、[C# 异步编程模式](https://code-maze.com/asynchronous-programming-patterns-dotnet/) |
| 134 | + |
| 135 | + |
| 136 | + |
| 137 | +在 `C#` 的历史发展过程中,异步编程经历过三种模式,分别为 |
| 138 | + |
| 139 | +- 异步编程模式 (Asynchronous Programming Model, APM) |
| 140 | +- 基于事件的异步模式 (Event-Based Asynchronous Pattern, EAP) |
| 141 | +- 基于任务的异步模式 (Task-Based Asynchrouous Pattern, TAP) |
| 142 | + |
| 143 | +1. APM |
| 144 | + 包含三种主要成分 |
| 145 | + |
| 146 | +- 两个方法分别表示开始和结束的异步操作 |
| 147 | +- 一个 `AsyncCallback` 的委托,用来表示操作的完成 |
| 148 | +- 可选的 `state` 属性表示依赖 |
| 149 | + |
| 150 | +```csharp |
| 151 | +public class ApmFileReader |
| 152 | +{ |
| 153 | + private byte[]? _buffer; |
| 154 | + private const int InputReportLength = 1024; |
| 155 | + private FileStream? _fileStream; |
| 156 | + |
| 157 | + public void BeginReadAsync() |
| 158 | + { |
| 159 | + _buffer = new byte[InputReportLength]; |
| 160 | + _fileStream = File.OpenRead("User.txt"); |
| 161 | + _fileStream.BeginRead(_buffer, 0, InputReportLength, ReadCallbackAsync, _buffer); |
| 162 | + } |
| 163 | + |
| 164 | + public void ReadCallbackAsync(IAsyncResult iResult) |
| 165 | + { |
| 166 | + _fileStream?.EndRead(iResult); |
| 167 | + var buffer = iResult.AsyncState as byte[]; |
| 168 | + } |
| 169 | +} |
| 170 | +``` |
| 171 | + |
| 172 | +2. EAP |
| 173 | + 使用 C# 的事件是实现异步操作,这些操作在各自的线程上操作,然后通过异步来通知。 |
| 174 | + |
| 175 | +```csharp |
| 176 | +public void GetUserAsync(int userId, object userState) |
| 177 | +{ |
| 178 | + AsyncOperation operation = AsyncOperationManager.CreateOperation(userState); |
| 179 | + |
| 180 | + ThreadPool.QueueUserWorkItem(state => |
| 181 | + { |
| 182 | + GetUserCompletedEventArgs args; |
| 183 | + try |
| 184 | + { |
| 185 | + var user = GetUser(userId); |
| 186 | + args = new GetUserCompletedEventArgs(null, false, user); |
| 187 | + } |
| 188 | + catch (Exception e) |
| 189 | + { |
| 190 | + Console.WriteLine(e.Message); |
| 191 | + args = new GetUserCompletedEventArgs(e, false, null); |
| 192 | + } |
| 193 | + |
| 194 | + operation.PostOperationCompleted(_operationFinished, args); |
| 195 | + |
| 196 | + }, userState); |
| 197 | +} |
| 198 | +``` |
| 199 | + |
| 200 | +3. TAP |
| 201 | + |
| 202 | +这是目前 `C#` 推荐的异步编程模型,通过 `Task`, `async` 和 `await` 关键字实现异步功能。 |
| 203 | + |
| 204 | +```csharp |
| 205 | +public Task<int> OperationName1Async(int param) |
| 206 | +{ |
| 207 | + // more code |
| 208 | + return Task.FromResult(1); |
| 209 | +} |
| 210 | + |
| 211 | +public async Task<int> OperationName2Async(int param) |
| 212 | +{ |
| 213 | + // more code with await |
| 214 | + return 1; |
| 215 | +} |
| 216 | +``` |
| 217 | + |
| 218 | +6、[C# 中 String 的优化机制](https://www.youtube.com/watch?v=Xeq8YGEyyp8&ab_channel=NickChapsas) |
| 219 | + |
| 220 | +String 类型在 `C#` 中是一种不可变的引用类型,但是有一个特性往往被大家忽略了,也就是 `Intern` 功能。简单来说就是 `CLR` 会将明面字符串在内存中储存一起来,如果有相同的变量使用同一个字符串,那么就会共享这一个内存空间。 |
| 221 | + |
| 222 | +```csharp |
| 223 | +var dotnetweekly1 = ".net weekly"; |
| 224 | +var dotnetweekly2 = ".net weekly"; |
| 225 | + |
| 226 | +Console.WriteLine(dotnetweekly1 == dotnetweekly2); //true |
| 227 | +Console.WriteLine(object.ReferenceEquals(dotnetweekly1, dotnetweekly2)); //true |
| 228 | +
|
| 229 | +string dotnet = ".net"; |
| 230 | +string weekly = " weekly"; |
| 231 | +string dotnetweekly = dotnet + weekly; |
| 232 | +Console.WriteLine(".net weekly" == dotnetweekly); //true |
| 233 | +Console.WriteLine(object.ReferenceEquals(".net weekly", dotnetweekly));// false; |
| 234 | +
|
| 235 | +const string dotnet3 = ".net"; |
| 236 | +const string weekly3 = " weekly"; |
| 237 | +string dotnetweekly3 = dotnet3 + weekly3; |
| 238 | +Console.WriteLine(".net weekly" == dotnetweekly3); //true |
| 239 | +Console.WriteLine(object.ReferenceEquals(".net weekly", dotnetweekly3));// true; |
| 240 | +
|
| 241 | +``` |
| 242 | + |
| 243 | +7、[Anders Hejlsberg 专访](https://www.aarthiandsriram.com/p/our-dream-conversation-anders-hejlsberg?sd=pf) |
| 244 | + |
| 245 | +播客博主采访了 `Anders Hejlsberg`,讨论了下面的内容: |
| 246 | + |
| 247 | +- Anders 早期的经历,包括电脑,编程语言和病毒 |
| 248 | +- Turbo Pascal 的经历 |
| 249 | +- 早期开发 `C#` 和 `.NET Framework` 经历 |
| 250 | +- Typescript 的现状 |
| 251 | +- 关于其他语言的看法,比如 `Rust`, `Golang` 等等。 |
| 252 | + |
| 253 | +## 开源项目 |
| 254 | + |
| 255 | +1、[stride](https://github.com/stride3d/stride) |
| 256 | + |
| 257 | + |
| 258 | + |
| 259 | +Stride 是最近 `C#` 开源的游戏引擎库。 |
| 260 | + |
| 261 | +2、[CommunityToolkit](https://github.com/CommunityToolkit/dotnet) |
| 262 | + |
| 263 | +CommunityToolkit` 是微软官方维护的一组工具类集合, 主要包含下面四种类型 |
| 264 | + |
| 265 | +- `CommunityToolkit.Common` 共有类集合 |
| 266 | +- `CommunityToolkit.Mvvm` MVVM 设计模式需要的类库 |
| 267 | +- `CommunityToolkit.Diagnoscitcs` 参数任何和错误检查的工具库 |
| 268 | +- `CommunityToolkit.HighPerformance` 高性能的 API 和类型库 |
0 commit comments