Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
92 commits
Select commit Hold shift + click to select a range
a0b0bea
Make sure the site works properly with Ruby 3.1
Feb 16, 2026
ad6370a
Add AV0100: Understand the boundaries of your codebase (#300)
dennisdoomen Mar 29, 2026
6899e40
Add AV0105: Use design patterns to communicate intent (#301)
dennisdoomen Mar 29, 2026
7bb56d3
Add AV0110: Prefer composition over class inheritance (#302)
dennisdoomen Mar 29, 2026
7c15003
Add AV0112: Apply the Principle of Least Surprise (#303)
dennisdoomen Mar 29, 2026
8d36acd
Add AV0115 guideline (#304)
dennisdoomen Mar 29, 2026
b0a2886
Add AV0120: You Ain't Gonna Need It (YAGNI) (#305)
dennisdoomen Mar 29, 2026
19f3c35
Add AV0125: Don't Repeat Yourself (DRY) within boundaries (#306)
dennisdoomen Mar 29, 2026
8ff5b65
Update explanation of code boundaries and coupling
dennisdoomen Mar 29, 2026
7f005dc
Add AV0135 guideline (#308)
dennisdoomen Mar 29, 2026
8d140f3
Add AV1582 guideline (#318)
dennisdoomen Mar 29, 2026
9ebaced
Add AV1608 guideline (#323)
dennisdoomen Mar 29, 2026
46c4087
Add AV1610 guideline (#324)
dennisdoomen Mar 29, 2026
7bd1063
Update AV1708 guideline (#372)
dennisdoomen Mar 29, 2026
76c7e50
Update AV1562 guideline (#368)
dennisdoomen Mar 29, 2026
a51fe48
Update AV1800 guideline (#375)
dennisdoomen Mar 29, 2026
792f093
Update AV1521 guideline (#361)
dennisdoomen Mar 29, 2026
4af00dc
Update AV1520 guideline (#360)
dennisdoomen Mar 29, 2026
b628a1a
Update AV1140 guideline (#356)
dennisdoomen Mar 29, 2026
128954a
Remove AV1530: Don't change a loop variable inside a `for` loop or a …
dennisdoomen Mar 29, 2026
3ffbfc8
Update AV1250 guideline (#358)
dennisdoomen Mar 29, 2026
196974d
Update AV1115 guideline (#352)
dennisdoomen Mar 29, 2026
b981cc1
Update AV1025 guideline (#351)
dennisdoomen Mar 29, 2026
9dc3c0e
Update AV1020 guideline (#350)
dennisdoomen Mar 29, 2026
25630e9
Update AV1011 guideline (#348)
dennisdoomen Mar 29, 2026
d57a494
Update AV1010 guideline (#347)
dennisdoomen Mar 29, 2026
bc2dafb
Update AV1003 guideline (#345)
dennisdoomen Mar 29, 2026
360ac88
Add AV1618 guideline (#326)
dennisdoomen Mar 29, 2026
7ea938a
Add AV1615: Prefer inline literals over constant variables in tests (…
dennisdoomen Mar 29, 2026
96303be
Update AV1835 guideline (#378)
dennisdoomen Mar 29, 2026
77987d5
Update AV1825 guideline (#377)
dennisdoomen Mar 29, 2026
3c324b7
Update AV1000: A class or interface should have a single purpose (#344)
dennisdoomen Mar 29, 2026
045161d
Remove AV2235 guideline (#342)
dennisdoomen Mar 29, 2026
8a93f83
Add AV1602: Postfix test classes with `Specs` instead of `Tests` (#321)
dennisdoomen Mar 30, 2026
8e700a8
Add AV1605: Test behavior, not implementation details (#322)
dennisdoomen Mar 30, 2026
750a94d
Add General Guidelines page (#385)
dennisdoomen Mar 30, 2026
bf43460
Add Testability Guidelines page (#386)
dennisdoomen Mar 30, 2026
d7cfeb6
Update Links & Articles page (#387)
dennisdoomen Mar 30, 2026
4a24803
Update C ov er An dS ty le s page (#384)
dennisdoomen Mar 30, 2026
291799d
Update AV2400 guideline (#382)
dennisdoomen Mar 30, 2026
4c9718f
Split minor site updates from PR 298 (#383)
dennisdoomen Apr 6, 2026
b22db49
Add AV1600 guideline (#320)
dennisdoomen Apr 11, 2026
775a61f
Add AV1578 guideline (#317)
dennisdoomen Apr 12, 2026
9a4d665
Update AV1706: Don't use abbreviations (#371)
dennisdoomen Apr 15, 2026
2b4abc7
Update AV1701 guideline (#370)
dennisdoomen Apr 15, 2026
5a10d39
Update AV1755: Only use `Async` or `TaskAsync` as a suffix when a met…
dennisdoomen Apr 15, 2026
e4cc35e
Clarify suffix usage for Async methods (#393)
bkoelman Apr 16, 2026
f1fc4c3
Update AV2305: Document all `public`, `protected` and `internal` type…
dennisdoomen May 3, 2026
34df958
Update AV2202: Prefer language syntax over explicit calls to underlyi…
dennisdoomen May 3, 2026
34a55f6
Update AV1820: Only use `async` for I/O-bound or long-running activit…
dennisdoomen May 3, 2026
4f5c57a
Remove AV1580 guideline (#392)
dennisdoomen May 9, 2026
26a6c20
AV0125: Consider duplicating simple logic across modules to reduce co…
dennisdoomen May 9, 2026
8bcb653
Update AV1554 guideline (#367)
dennisdoomen May 9, 2026
8acf25c
Update AV1553 guideline (#366)
dennisdoomen May 9, 2026
99cec88
Update AV1546 guideline (#365)
dennisdoomen May 9, 2026
feeef8e
Update AV1545: Don't use an `if`-`else` construct instead of a simple…
dennisdoomen May 9, 2026
26a150c
Update AV1523 guideline (#362)
dennisdoomen May 9, 2026
df57cdf
Update AV1500: Methods should not exceed 15 statements (#359)
dennisdoomen May 9, 2026
9b7ccfe
Remove AV1230 guideline (#357)
dennisdoomen May 9, 2026
3c615f7
Update AV1137: Keep parameters as specific and narrow as possible (#355)
dennisdoomen May 9, 2026
dbcf0c2
Update AV1130: Return interfaces to unchangeable collections (#354)
dennisdoomen May 9, 2026
4665e9f
Update AV1125: Don't expose stateful objects through static members (…
dennisdoomen May 9, 2026
ca303e6
Update AV1013: Don't cast a base class to one of its derived classes …
dennisdoomen May 10, 2026
eeeda74
Add LSP example with polymorphism to AV1011 (#396)
dennisdoomen May 10, 2026
3f61b5a
Update AV1004: Use an interface rather than a base class to support m…
dennisdoomen May 10, 2026
8b7b09a
Remove AV2307 guideline (#343)
dennisdoomen May 10, 2026
185189d
Remove AV2221 guideline (#341)
dennisdoomen May 10, 2026
a974c68
Remove AV2201 guideline (#339)
dennisdoomen May 10, 2026
a2e8469
Remove AV1738 guideline (#338)
dennisdoomen May 10, 2026
dd11467
Remove AV1737 guideline (#337)
dennisdoomen May 10, 2026
890a73b
Remove AV1568 guideline (#336)
dennisdoomen May 10, 2026
060ef45
Remove AV1532: Avoid nested loops (#334)
dennisdoomen May 10, 2026
f210e50
Remove AV1525 guideline (#333)
dennisdoomen May 10, 2026
48e49e0
Remove AV1510 guideline (#332)
dennisdoomen May 10, 2026
bfc3a86
Remove AV1220 guideline (#331)
dennisdoomen May 10, 2026
2d515fb
Add AV2308: Document what a member tries to do, not what it does or h…
dennisdoomen May 10, 2026
566695e
Add AV2225: Use deconstruction to simplify variable assignments (#329)
dennisdoomen May 10, 2026
b6ca705
Add AV1622: Test concrete implementations as part of a larger integra…
dennisdoomen May 10, 2026
22d1f03
Add AV1620: Test reusable components separately from their consumers …
dennisdoomen May 10, 2026
380f20f
Add AV1585: Make properties required when they must be set during ini…
dennisdoomen May 10, 2026
6da5598
Add AV1155: Use the `field` keyword in auto-properties when additiona…
dennisdoomen May 10, 2026
454b59e
Add AV1150: Avoid local functions (#315)
dennisdoomen May 10, 2026
bb03ad5
Add AV1145: Use extension members to add behavior without modifying t…
dennisdoomen May 10, 2026
6fc3b6d
Add AV1035: Use primary constructors when they improve readability (#…
dennisdoomen May 10, 2026
619af9b
Add AV1032: Consider a delegate instead of an interface with a single…
dennisdoomen May 14, 2026
9d6a0d6
Add AV1030: Know when to use a record and when to use a class (#311)
dennisdoomen May 14, 2026
cde9d26
Add AV1002: Only pass things to a constructor that most or all member…
dennisdoomen May 14, 2026
01259e1
Remove AV2207 guideline (#340)
dennisdoomen May 14, 2026
b3ee108
Add AV0130: Apply the three pillars of object-oriented programming (#…
dennisdoomen May 14, 2026
a3d7df4
Fix c# fencing to use csharp in assertion-comparison.html
dennisdoomen May 14, 2026
bba7004
Remove severity field from all rules
dennisdoomen May 14, 2026
1bd7b0f
Merge master into remove-severity-from-rules to resolve conflicts
Copilot May 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions _config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@ minimal_mistakes_skin : "default" # "air", "aqua", "contrast", "dark", "dirt"

# Site Settings
locale : "en-US"
title : "C# Coding Guidelines for all versions up to and including v10"
title : "C# Coding Guidelines for all versions up to and including v14"
title_separator : "-"
name : "Dennis Doomen"
description : "C# Coding Guidelines for all versions up to and including v10"
description : "C# Coding Guidelines for all versions up to and including v14"
url : "https://csharpcodingguidelines.com/" # the base hostname & protocol for your site e.g. "https://mmistakes.github.io"
baseurl : # the subpath of your site, e.g. "/blog"
repository : "dennisdoomen/csharpguidelines" # GitHub username/repo-name e.g. "mmistakes/minimal-mistakes"
Expand Down
4 changes: 4 additions & 0 deletions _data/navigation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ sidebar:

- title: Guidelines
children:
- title: General (AV0100)
url: /general-guidelines/
- title: Class Design (AV1000)
url: /class-design-guidelines/
- title: Member Design (AV1100)
Expand All @@ -32,6 +34,8 @@ sidebar:
url: /misc-design-guidelines/
- title: Maintainability (AV1500)
url: /maintainability-guidelines/
- title: Testability (AV1600)
url: /testability-guidelines/
- title: Naming (AV1700)
url: /naming-guidelines/
- title: Performance (AV1800)
Expand Down
27 changes: 13 additions & 14 deletions _includes/0001_Introduction.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,25 @@
## 1.1. What is this?

This document attempts to provide guidelines (or coding standards if you like) for all versions of C# up to and including v10 that are both valuable and pragmatic. Of course, if you create such a document you should practice what you preach. So rest assured, these guidelines are representative to what we at [Aviva Solutions](https://www.avivasolutions.nl) do in our day-to-day work. Notice that not all guidelines have a clear rationale. Some of them are simply choices we made at Aviva Solutions. In the end, it doesn't matter what choice you made, as long as you make one and apply it consistently.
This document attempts to provide guidelines (or coding standards if you like) for all versions of C# up to and including v14 that are both valuable and pragmatic. Of course, if you create such a document you should practice what you preach. So rest assured, these guidelines are representative to what we at [Aviva Solutions](https://www.avivasolutions.nl) do in our day-to-day work. Notice that not all guidelines have a clear rationale. Some of them are simply choices we made at Aviva Solutions. In the end, it doesn't matter what choice you made, as long as you make one and apply it consistently.

These guidelines are also used many projects inside and outside Aviva Solutions, in particular the [.NET Starter Kit](https://github.com/dennisdoomen/dotnet-starter-kit), a great companion project to see these guidelines in action.

## 1.2. Why would you use this document?

Although some might see coding guidelines as undesired overhead or something that limits creativity, this approach has already proven its value for many years. This is because not every developer:

- is aware that code is generally read 10 times more than it is changed;
- is aware of the potential pitfalls of certain constructs in C#;
- is up to speed on certain conventions when using the .NET Framework such as `IDisposable`, `async`/`await`, or the deferred execution nature of LINQ;
- is up to speed on certain conventions when using .NET such as `IDisposable`, `async`/`await`, or the deferred execution nature of LINQ;
- is aware of the impact of using (or neglecting to use) particular solutions on aspects like security, performance, multi-language support, etc;
- realizes that not every developer is as capable, skilled or experienced to understand elegant, but potentially very abstract solutions;

## 1.3. Basic principles

There are many unexpected things I run into during my work as a consultant, each deserving at least one guideline. Unfortunately, I still need to keep this document within a reasonable size. But unlike what some junior developers believe, that doesn't mean that something is okay just because it is not mentioned in this document.

In general, if I have a discussion with a colleague about a smell that this document does not cover, I'll refer back to a set of basic principles that apply to all situations, regardless of context. These include:
In general, if I have a discussion with a colleague about a smell that this document does not cover, I'll refer back to the [General Guidelines](/general-guidelines/) that apply to all situations, regardless of context. The only remaining exception is:

- The Principle of Least Surprise (or Astonishment): you should choose a solution that everyone can understand, and that keeps them on the right track.
- Keep It Simple Stupid (a.k.a. KISS): the simplest solution is more than sufficient.
- You Ain't Gonna Need It (a.k.a. YAGNI): create a solution for the problem at hand, not for the ones you think may happen later on. Can you predict the future?
- Don't Repeat Yourself (a.k.a. DRY): avoid duplication within a component, a source control repository or a [bounded context](http://martinfowler.com/bliki/BoundedContext.html), without forgetting the [Rule of Three](http://lostechies.com/derickbailey/2012/10/31/abstraction-the-rule-of-three/) heuristic.
- The [four principles of object-oriented programming](https://github.com/TelerikAcademy/Object-Oriented-Programming/tree/master/Topics/04.%20OOP-Principles-Part-1): encapsulation, abstraction, inheritance and polymorphism.
- In general, generated code should not need to comply with coding guidelines. However, if it is possible to modify the templates used for generation, try to make them generate code that complies as much as possible.

Regardless of the elegance of someone's solution, if it's too complex for the ordinary developer, exposes unusual behavior, or tries to solve many possible future issues, it is very likely the wrong solution and needs redesign. The worst response a developer can give you to these principles is: "But it works?".
Expand All @@ -31,17 +28,19 @@ Regardless of the elegance of someone's solution, if it's too complex for the or

- Ask all developers to carefully read this document at least once. This will give them a sense of the kind of guidelines the document contains.
- Make sure there are always a few hard copies of the [Cheat Sheet](https://github.com/dennisdoomen/CSharpGuidelines/releases/latest) close at hand.
- Include the most critical coding guidelines on your [Project Checklist](https://www.continuousimprover.com/2010/03/alm-practices-5-checklists.html) and verify the remainder as part of your [Peer Review](https://www.continuousimprover.com/2010/02/tfs-development-practices-part-2-peer.html).
- Include the most critical coding guidelines on your [Pull Request template](https://docs.github.com/en/communities/using-templates-to-encourage-useful-issues-and-pull-requests/creating-a-pull-request-template-for-your-repository) and verify the remainder as part of your [Peer Review](https://www.continuousimprover.com/2010/02/tfs-development-practices-part-2-peer.html).
- Consider forking the [original sources](https://github.com/dennisdoomen/csharpguidelines) on [GitHub](https://github.com/) and create your own [internal](https://github.com/dennisdoomen/csharpguidelines/blob/master/LICENSE.md) version of the document.
- Jetbrain's [ReSharper](http://www.jetbrains.com/resharper/) and their fully fledged Visual Studio replacement [Rider](https://www.jetbrains.com/rider/), has an intelligent code inspection engine that, with some configuration, already supports many aspects of the Coding Guidelines. It automatically highlights any code that does not match the rules for naming members (e.g. Pascal or Camel casing), detects dead code, and many other things. One click of the mouse button (or the corresponding keyboard shortcut) is usually enough to fix it.
- ReSharper also has a File Structure window that displays an overview of the members of your class or interface, and allows you to easily rearrange them using a simple drag-and-drop action.
- JetBrains' [ReSharper](https://www.jetbrains.com/resharper/) and their fully fledged Visual Studio replacement [Rider](https://www.jetbrains.com/rider/), has an intelligent code inspection engine that, with some configuration, already supports many aspects of the Coding Guidelines. It automatically highlights any code that does not match the rules for naming members (e.g. Pascal or Camel casing), detects dead code, and many other things. One click of the mouse button (or the corresponding keyboard shortcut) is usually enough to fix it.
- Both ReSharper and Rider have a File Structure window that displays an overview of the members of your class or interface, and allows you to easily rearrange them using a simple drag-and-drop action.
- [CSharpGuidelinesAnalyzer](https://github.com/bkoelman/CSharpGuidelinesAnalyzer) verifies over 40 of our guidelines, while typing code in Visual Studio 2017-2022 and during CI builds. An updated Resharper settings file is included.
- Many of these guidelines are also enforced by [Roslyn analyzers](https://learn.microsoft.com/en-us/visualstudio/code-quality/roslyn-analyzers-overview). You can configure them centrally in a `Directory.Build.props` file to apply them to all projects in your solution.
- If you need to use newer C# language features in projects targeting older .NET versions, consider [PolySharp](https://github.com/Sergio0694/PolySharp). It provides polyfills for many modern C# features, allowing you to write modern C# even when targeting older runtimes.

## 1.5. Why did we create it?

The idea started in 2002 when Vic Hartog (Philips Medical Systems) and I were assigned the task of writing up a [coding standard](http://www.tiobe.com/content/paperinfo/gemrcsharpcs.pdf) for C# 1.0. Since then, I've regularly added, removed and changed rules based on experiences, feedback from the community and new tooling support offered by a continuous stream of new developments in the .NET ecosystem. Special thanks go to [Bart Koelman](https://github.com/bkoelman) for being a very active contributor over all those years.
The idea started in 2002 when Vic Hartog (Philips Medical Systems) and I were assigned the task of writing up a coding standard for C# 1.0. Since then, I've regularly added, removed and changed rules based on experiences, feedback from the community and new tooling support offered by a continuous stream of new developments in the .NET ecosystem. Special thanks go to [Bart Koelman](https://github.com/bkoelman) for being a very active contributor over all those years.

Additionally, after reading [Robert C. Martin](https://sites.google.com/site/unclebobconsultingllc/)'s book [Clean Code: A Handbook of Agile Software Craftsmanship](http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882), I became a big fan of his ideas and decided to include some of his smells and heuristics as guidelines. Notice though, that this document is in no way a replacement for his book. I sincerely recommend that you read his book to gain a solid understanding of the rationale behind his recommendations.
Additionally, after reading [Robert C. Martin](https://cleancoder.com/)'s book [Clean Code: A Handbook of Agile Software Craftsmanship](http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882), I became a big fan of his ideas and decided to include some of his smells and heuristics as guidelines. Notice though, that this document is in no way a replacement for his book. I sincerely recommend that you read his book to gain a solid understanding of the rationale behind his recommendations.

I've also decided to include some design guidelines in addition to simple coding guidelines. They are too important to ignore and have a big influence in reaching high quality code.

Expand All @@ -59,7 +58,7 @@ To help you in this decision, I've assigned a level of importance to each guidel

## 1.7. Feedback and disclaimer

This document has been compiled using many contributions from community members, blog posts, on-line discussions and two decades of developing in C#. If you have questions, comments or suggestions, just let me know by sending me an email at [dennis.doomen@avivasolutions.nl](mailto:dennis.doomen@avivasolutions.nl), [creating an issue](https://github.com/dennisdoomen/csharpguidelines/issues) or Pull Request on GitHub, ping me at [http://twitter.com/ddoomen](http://twitter.com/ddoomen) or join the [Gitter discussions](https://gitter.im/dennisdoomen/CSharpGuidelines). I will try to revise and republish this document with new insights, experiences and remarks on a regular basis.
This document has been compiled using many contributions from community members, blog posts, on-line discussions and two decades of developing in C#. If you have questions, comments or suggestions, just let me know by sending me an email at [dennis.doomen@avivasolutions.nl](mailto:dennis.doomen@avivasolutions.nl), [creating an issue](https://github.com/dennisdoomen/csharpguidelines/issues) or Pull Request on GitHub, or ping me at [https://bsky.app/profile/ddoomen.bsky.social](https://bsky.app/profile/ddoomen.bsky.social) or [https://mastodon.social/@ddoomen](https://mastodon.social/@ddoomen). I will try to revise and republish this document with new insights, experiences and remarks on a regular basis.

Notice though that it merely reflects my view on proper C# code so Aviva Solutions will not be liable for any direct or indirect damages caused by applying the guidelines of this document. This document is published under a Creative Commons license, specifically the [Creative Commons Attribution-ShareAlike 4.0](http://creativecommons.org/licenses/by-sa/4.0/) license.

Expand Down
4 changes: 2 additions & 2 deletions _includes/assertion-comparison.html
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@
<tbody>
<tr>
<td markdown="1">
```c#
```csharp
{{ example.old }}
```
</td>
<td markdown="1">
```c#
```csharp
{{ example.new }}
```
</td>
Expand Down
2 changes: 1 addition & 1 deletion _layouts/rule-category.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@
{% if rule.custom_prefix != nil %}
{% assign full_rule_id = rule.custom_prefix | append: rule.rule_id %}
{% endif %}
<h3 id="{{ full_rule_id }}">{{ rule.title | markdownify | replace: "<p>", "" | replace: "</p>", "" }} ({{ full_rule_id }}) <img src="/assets/images/{{ rule.severity }}.png" /></h3>
<h3 id="{{ full_rule_id }}">{{ rule.title | markdownify | replace: "<p>", "" | replace: "</p>", "" }} ({{ full_rule_id }})</h3>
{{ rule.content }}
{% endfor %}
2 changes: 1 addition & 1 deletion _pages/0000_CoverAndStyles.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ NOTE: Requires Markdown Extra. See http://michelf.ca/projects/php-markdown/extra
Coding Guidelines
</div><br/>
<div class="subTitle">
for all C# versions up to v10
for all C# versions up to v14
</div>
<br/>
<div class="author">
Expand Down
10 changes: 10 additions & 0 deletions _pages/0100_GeneralGuidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: General Guidelines
permalink: /general-guidelines/
classes: wide
search: true
sidebar:
nav: "sidebar"
rule_category: general
layout: rule-category
---
10 changes: 10 additions & 0 deletions _pages/1600_TestabilityGuidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
---
title: Testability Guidelines
permalink: /testability-guidelines/
classes: wide
search: true
sidebar:
nav: "sidebar"
rule_category: testability
layout: rule-category
---
9 changes: 3 additions & 6 deletions _pages/9999_ResourcesAndLinks.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ sidebar:
In addition to the many links provided throughout this document, I'd like to recommend the following books, articles and sites for everyone interested in software quality:

* [Code Complete: A Practical Handbook of Software Construction](http://www.amazon.com/Code-Complete-Practical-Handbook-Construction/dp/0735619670) (Steve McConnel)
One of the best books I've ever read. It deals with all aspects of software development, and even though the book was originally written in 2004 you'll be surprised when you see how accurate it still is. I wrote a [review](http://www.continuousimprover.com/2009/07/book-review-code-complete-2nd-edition.html) in 2009 if you want to get a sense of its contents.
One of the best books I've ever read. It deals with all aspects of software development, and even though the book was originally written in 2004 you'll be surprised when you see how accurate it still is.

* [The Art of Agile Development](http://www.amazon.com/Art-Agile-Development-James-Shore/dp/0596527675) (James Shore)
Another great all-encompassing trip through the many practices preached by processes like Scrum and Extreme Programming. If you're looking for a quick introduction with a pragmatic touch, make sure you read James's book.
Expand All @@ -20,11 +20,8 @@ The book that started my interest for both Domain-Driven Design and Test-Driven
* [Jeremy D. Miller's Blog](https://jeremydmiller.com/)
Jeremy has written some excellent blog posts on Test-Driven Development, Design Patterns and design principles. I've learned a lot from his real-life and practical insights.

* [LINQ Framework Design Guidelines](https://blogs.msdn.microsoft.com/mirceat/2008/03/12/linq-framework-design-guidelines/)
A set of rules and recommendations that you should adhere to when creating your own implementations of `IQueryable`.

* [Guidance on Asynchronous Programming](https://github.com/davidfowl/AspNetCoreDiagnosticScenarios/blob/master/AsyncGuidance.md) (David Fowler)
Best practices for `async`/`await` with examples of bad and good patterns of how to write asynchronous code.

* [Best Practices for c# async/await](https://msdn.microsoft.com/en-us/magazine/jj991977.aspx)
Older (but still valid) overview of crucial practices to follow when adopting `async` and `await` in your own code base.
* [Best Practices for C# async/await](https://learn.microsoft.com/en-us/archive/msdn-magazine/2013/march/async-await-best-practices-in-asynchronous-programming)
Overview of crucial practices to follow when adopting `async` and `await` in your own code base.
14 changes: 14 additions & 0 deletions _rules/0100.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
---
rule_id: 0100
rule_category: general
title: Understand the boundaries of your codebase
---
Every codebase has logical and physical boundaries: a microservice, a module, a library, or a bounded context. Code within a boundary can evolve freely and share abstractions, but code that crosses a boundary should go through well-defined contracts (e.g. interfaces, DTOs, or API contracts).

Understanding these boundaries matters for several reasons:

- It prevents unnecessary coupling between components that have different lifecycles or are maintained by different teams.
- It guides when to introduce an abstraction (across a boundary) versus when to skip it (within a boundary).
- It helps decide when to duplicate small pieces of logic instead of pulling in a shared dependency that would increase coupling.

**Tip:** When in doubt whether something belongs inside or outside a boundary, ask yourself: "If this boundary were a separate deployable unit, would this dependency still make sense?"
17 changes: 17 additions & 0 deletions _rules/0105.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
rule_id: 0105
rule_category: general
title: Use design patterns to communicate intent
---
[Design patterns](https://en.wikipedia.org/wiki/Software_design_pattern) are proven, named solutions to recurring design problems. Using them lets you communicate the structure and intent of your code in a single recognizable term: *Repository*, *Factory*, *Strategy*, *Observer*, *Decorator*, and so on.

When you refactor a complex piece of code into a well-known pattern:
- Other developers immediately understand the structure without having to reverse-engineer it.
- The code gains a shared vocabulary that transcends the codebase.
- It becomes easier to reason about responsibilities and extension points.

> [!TIP]
> If you cannot assign a single design pattern to a class, it may be doing more than one thing. Consider splitting it up.

> [!TIP]
> Don't force a pattern onto code that doesn't need it — a pattern is a tool, not a goal. Prefer simplicity when the problem doesn't warrant the extra structure.
Loading