A page to store links, blogs, comments, and packages that I consider beneficial for learning, developing and writing clean .NET code.
- Keep it simple, stupid.
- Focus on the requirement, not the technology.
- Code should read like a story.
- Keep as much as possible in code and in .NET. For example, don't use Angular if all that is required are a few web pages, use Razor Pages instead.
- Prefer locality of behaviour and vertical slice architecture over multiple layers of components.
- Minimise all external dependencies. For example, don't place just 3 or 4 email templates that rarely change, in blob storage. This would mean a dependency on the blob storage service. Instead, place them in C# classes.
- Following on from point above, keep as much work as possible in the local code.
- Keep all configuration local and change depending on environment. Don't automatically use web app config when it's only storing values that never need to be changed in the web app config settings of Azure portal.
- Minimise dependency on specific cloud providers.
- Prefer build and deployment process in code and CLI rather than YAML based pipelines.
- A dependency is a liability. Reduce all external dependencies as much as posssible.
Mirosoft Commercial Software Engineering team, CSE Code with engineering playbook
Engineering Fundamentals Checklist
ASPNET Core engineering guidelines
<PackageReference Include="AsyncFixer" Version="1.6.0">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
<PackageReference Include="NetEscapades.AspNetCore.SecurityHeaders" Version="0.18.0" />
<PackageReference Include="SonarAnalyzer.CSharp" Version="8.52.0.60960">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
<PrivateAssets>all</PrivateAssets>
</PackageReference>
- Fluent Results
- BenchmarkDotNet.Org
- DbUp
- Serilog
- HangFire
- Scrutor
- FluentValidation
- AutoFixture
- FluentAssertions
- Quartz.Net
- Wolverine
- Elsa Core
- FastEndpoints
- Nuke.Build
- LINQKit
- EFCore.BulkExtensions
- AngleSharp
- Playwright
- CliWrap
- Bogus
- Andrew Lock - Small package to allow adding security headers to ASP.NET Core websites
Project Orleans
AZD
Microsoft Kiota
- Azure Cloud Blogs
- Microsoft Developer Blogs
- Steve ‘Ardalis’ Smith
- Vladimir Khorikov
- Jimmy Bogard
- Mark Heath
- Khalid Abuhakmeh
- Derek Comartin
- Bart Wullem
- Rick Strahl
- Jeremy Miller
- Andrew Lock
- Oscar Dudycz
- The Morning Brew
- The Morning Dew
- Raw Coding
- Nick Chapsas
Examples and Tutorials of Event Sourcing in .NET - Oskar Dudycz
- Microsoft REST API Guidelines
- C# 9.0: Pattern Matching in Switch Expressions - Thomas Claudis Huber
- Domain-Driven Design Fundamentals By Julie Lerman and Steve Smith - Pluralsight
- The Best Way to Validate Your Option Settings in .NET - Nick Chapsas - related Andrew Lock, Adding validation to strongly typed configuration objects in .NET 6
- Creating Discoverable HTTP APIs with ASP.NET Core 5 Web API - Microsoft .NET Blog - 4th Feb, 2021
- Open-source HTTP API packages and tools - Microsoft .NET Blog - 11th Feb, 2021
https://www.hanselman.com/blog/editorconfig-code-formatting-from-the-command-line-with-net-cores-dotnet-format-global-tool - Stuart’s comment.
We focus on having better code structure instead of micro coding rules which apply to one part of a statement or identifier declaration.
Variable naming, whether or not you use VAR and the like are minor minor worries.
Our solution:
- Getting the business logic right
- Having methods follow the business logic instead of misappropriated patterns
- Checking for errors
- Using guard clauses
- Avoid using the self-documenting code cliche instead of documenting the business purpose and logic for each unit of work
- Having code where the reading level is Junior developer
- Limiting the number of identifiers each line of code has access to
- Keeping code together for a single job, following locality of reference, not segregating code out into dozens of components for a single task just for whiteboard diagramming purposes. Indirection in reading the code for a business task from the first line to the last for the business task should be easy and not require the reader to look at dozens of source code files.
- Avoiding magic framework induced indirection. Code used should be referenced by a method and not through levels of framework interconnects. Breaking down business logic into X areas interconnected via framework indirection considerably lowers the maintainability of the code.
- Code should not require reader to be an expert in the framework, ASP.NET MVC structure, ... because that knowledge is an order of magnitude harder to find 3 years after the code goes into production. Think finding an Angular 1.0 expert now 5+ years after that framework was released
- Avoiding custom build steps
- Avoiding custom build tools
- important - Not buying or using tools, libraries, frameworks which hit 75% of our needs but need customization to work. It's a ticking maintenance bomb. The underlying tool, framework, library should have the functionality already in it and not require customization.
Newer versions of the Azure SDK have default resiliency strategies for many Azure services. Details of them can be found at: https://learn.microsoft.com/en-us/azure/architecture/best-practices/retry-service-specific
Using the Azure SDKs means resiliency is implemented by default for many services.
Entity Framework Core has an option for connection resiliency, which is .EnableRetryOnFailure(). For example:
services.AddDbContext(options => options.UseSqlServer(hostContext.Configuration.GetSection("QlikDatabaseConnection").Value, sqlOptions => { sqlOptions.EnableRetryOnFailure(); })); Details can be found at: https://learn.microsoft.com/en-us/ef/core/miscellaneous/connection-resiliency
.NET 8 has a new package available which provides updated default resiliency strategies based on Polly v8. Include the package Microsoft.Extensions.Http.Resilience, add .AddStandardResilienceHandler() to a HttpClient implementation and the new default strategies will be enabled. For example:
services.AddHttpClient().AddStandardResilienceHandler(); Details at: https://devblogs.microsoft.com/dotnet/building-resilient-cloud-services-with-dotnet-8/ and https://learn.microsoft.com/en-us/dotnet/core/resilience/http-resilience?tabs=dotnet-cli
Microsoft testing library for times and ILogger - Fake it 'til you make it to production