@@ -47,4 +47,184 @@ if (result.IsSuccess)
4747var chainResult = ValidateEmail (" test@example.com" )
4848 .Then (email => ProcessEmail (email ))
4949 .Then (processed => SaveToDatabase (processed ));
50+ ```
51+
52+ ## Code Style & Conventions
53+
54+ ** Framework Configuration:**
55+ - Target: .NET 9.0
56+ - Nullable reference types enabled
57+ - TreatWarningsAsErrors = true
58+ - EnableNETAnalyzers = true
59+
60+ ** Formatting (from .editorconfig):**
61+ - 4 spaces for C# indentation
62+ - CRLF line endings
63+ - Opening braces on new lines (` csharp_new_line_before_open_brace = all ` )
64+ - Spaces around binary operators
65+ - No space after cast: ` (int)value `
66+
67+ ** C# Style Preferences:**
68+ - Use ` var ` only when type is apparent: ` var user = GetUser(); `
69+ - Prefer explicit types for built-ins: ` int count = 0; ` not ` var count = 0; `
70+ - Expression-bodied properties preferred: ` public string Name => _name; `
71+ - Pattern matching over is/as: ` if (obj is User user) `
72+ - Null conditional operators: ` user?.Name ` over null checks
73+
74+ ** Naming Conventions:**
75+ - PascalCase for public members, types, constants
76+ - No prefixes for interfaces, fields, or private members
77+ - Method names should be descriptive: ` ValidateEmailAddress() ` not ` Validate() `
78+
79+ ## Testing Patterns
80+
81+ ** Test Framework:**
82+ - xUnit for test framework
83+ - FluentAssertions for readable assertions
84+ - Coverlet for code coverage
85+
86+ ** Test Structure:**
87+ ``` csharp
88+ [Fact ]
89+ public void Method_Scenario_ExpectedResult ()
90+ {
91+ // Arrange
92+ var input = CreateTestData ();
93+
94+ // Act
95+ var result = systemUnderTest .Method (input );
96+
97+ // Assert
98+ result .IsSuccess .Should ().BeTrue ();
99+ result .Value .Should ().NotBeNull ();
100+ }
101+ ```
102+
103+ ## Best Practices
104+
105+ ** DO ✅ - Result Pattern Usage:**
106+ ``` csharp
107+ // Use Result for operations that can fail
108+ public Result < User > GetUser (int id )
109+ {
110+ var user = _repository .FindById (id );
111+ return user != null
112+ ? Result <User >.Succeed (user )
113+ : Result <User >.FailNotFound ($" User {id } not found" );
114+ }
115+
116+ // Chain operations using railway-oriented programming
117+ public Result < Order > ProcessOrder (OrderDto dto )
118+ {
119+ return ValidateOrder (dto )
120+ .Then (CreateOrder )
121+ .Then (CalculateTotals )
122+ .Then (SaveOrder );
123+ }
124+
125+ // Provide specific error information
126+ public Result ValidateEmail (string email )
127+ {
128+ if (string .IsNullOrEmpty (email ))
129+ return Result .FailValidation ((" email" , " Email is required" ));
130+
131+ if (! email .Contains (" @" ))
132+ return Result .FailValidation ((" email" , " Invalid email format" ));
133+
134+ return Result .Succeed ();
135+ }
136+
137+ // Use CollectionResult for paginated data
138+ public CollectionResult < Product > GetProducts (int page , int pageSize )
139+ {
140+ var products = _repository .GetPaged (page , pageSize );
141+ var total = _repository .Count ();
142+ return CollectionResult <Product >.Succeed (products , page , pageSize , total );
143+ }
144+ ```
145+
146+ ** DON'T ❌ - Anti-patterns:**
147+ ``` csharp
148+ // DON'T: Throw exceptions from Result-returning methods
149+ public Result < User > GetUser (int id )
150+ {
151+ if (id <= 0 )
152+ return Result <User >.FailValidation ((" id" , " ID must be positive" )); // ✅
153+ // NOT: throw new ArgumentException("Invalid ID"); // ❌
154+ }
155+
156+ // DON'T: Ignore Result values
157+ var result = UpdateUser (user );
158+ if (result .IsFailed )
159+ return result ; // ✅ Handle the failure
160+
161+ // DON'T: Mix Result and exceptions
162+ // DON'T: Create generic error messages - be specific
163+ return Result .Fail (" User creation failed" , " Email already exists" ); // ✅
164+ ```
165+
166+ ** Performance Guidelines:**
167+ 1 . ` Result ` and ` Result<T> ` are structs - avoid boxing
168+ 2 . Use railway-oriented programming to avoid intermediate variables
169+ 3 . Cache common Problem instances for frequent errors
170+ 4 . Use ` ConfigureAwait(false) ` in library code
171+
172+ ## Framework Integration
173+
174+ ** ASP.NET Core:**
175+ - Controllers can return Result types directly
176+ - Automatic HTTP status code mapping from Problem Details
177+ - Built-in filters for Result handling
178+
179+ ** Orleans:**
180+ - Use ` UseOrleansCommunication() ` for automatic serialization
181+ - Result types work across grain boundaries
182+ - Problem Details preserved in distributed calls
183+
184+ ** Command Pattern:**
185+ - Built-in command infrastructure with idempotency
186+ - Commands implement ` ICommand ` or ` ICommand<T> `
187+ - Automatic validation and result wrapping
188+
189+ ## Common Patterns
190+
191+ ** Validation:**
192+ ``` csharp
193+ private Result ValidateDto (CreateUserDto dto )
194+ {
195+ var errors = new List <(string field , string message )>();
196+
197+ if (string .IsNullOrWhiteSpace (dto .Email ))
198+ errors .Add ((" email" , " Email is required" ));
199+
200+ return errors .Any ()
201+ ? Result .FailValidation (errors .ToArray ())
202+ : Result .Succeed ();
203+ }
204+ ```
205+
206+ ** Error Recovery:**
207+ ``` csharp
208+ public async Task < Result < User >> GetUserWithFallback (int id )
209+ {
210+ return await GetUser (id )
211+ .CompensateAsync (async error =>
212+ {
213+ var archived = await GetArchivedUser (id );
214+ return archived ?? Result <User >.FailNotFound ($" User {id } not found" );
215+ });
216+ }
217+ ```
218+
219+ ** Aggregating Results:**
220+ ``` csharp
221+ public Result < Order > CreateOrder (List < OrderItem > items )
222+ {
223+ var validationResults = items .Select (ValidateItem );
224+ var combinedResult = Result .Combine (validationResults );
225+
226+ return combinedResult .IsSuccess
227+ ? ProcessOrder (items )
228+ : Result <Order >.Fail (combinedResult .Problem );
229+ }
50230```
0 commit comments