You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -76,7 +72,7 @@ The `Thinktecture.Runtime.Extensions.SourceGenerator` project contains multiple
76
72
77
73
#### Analyzers
78
74
1.**`ThinktectureRuntimeExtensionsAnalyzer`**: Main diagnostic analyzer with 40+ diagnostic rules that validates correct usage of library features
79
-
-**Type structure**: Ensures types with `[SmartEnum]`, `[ValueObject]`, or `[Union]` are `partial`, are class/struct, not generic (except regular unions and complex value objects), not nested in generic types
75
+
-**Type structure**: Ensures types with `[SmartEnum]`, `[ValueObject]`, `[Union]`, or `[AdHocUnion]` are `partial`, are class/struct, not generic (except regular unions and complex value objects), not nested in generic types
80
76
-**Constructor rules**: Validates constructors are private, no primary constructors allowed
81
77
-**Member validation**:
82
78
- Fields must be readonly, properties must be readonly (no set) or have private init
@@ -106,7 +102,7 @@ The `Thinktecture.Runtime.Extensions.SourceGenerator` project contains multiple
106
102
107
103
#### 1. Smart Enums
108
104
**Keyless**: `[SmartEnum]` - Type-safe enums without underlying values
109
-
- Items are defined as public static readonly/const fields or properties
105
+
- Items are defined as public static readonly fields
110
106
- Cannot use comparison operators (no key to compare)
@@ -152,7 +148,7 @@ The `Thinktecture.Runtime.Extensions.SourceGenerator` project contains multiple
152
148
- Validation: Implement `ValidateFactoryArguments` (preferred) or `ValidateConstructorArguments`
153
149
154
150
#### 3. Discriminated Unions
155
-
**Ad-hoc Unions**: `[Union<T1, T2>]` through `[Union<T1, T2, T3, T4, T5>]` OR `[AdHocUnion(typeof(T1), typeof(T2), ...)]`
151
+
**Ad-hoc Unions**: `[Union<T1, T2>]` through `[Union<T1, T2, T3, T4, T5>]`, or non generic `[AdHocUnion(Type t1, Type t2, Type? t3, Type? t4, Type? t5)]`
156
152
- Simple combination of 2-5 types without inheritance
157
153
- Two syntaxes available:
158
154
-**Generic** (recommended): `[Union<string, int>]` - simpler syntax for most cases
@@ -283,15 +279,22 @@ The source generators follow a consistent pattern:
283
279
284
280
## Testing Strategy
285
281
- xUnit for unit testing
286
-
- AwesomeAssertions for readable assertions
287
-
- Verify.Xunit for snapshot testing
282
+
- Analyze whether `Theory` can be used for parameterized tests, before considering separate tests for each case
283
+
- Edge cases must be tested as well
284
+
- AwesomeAssertions for readable assertions (uses same api as FluentAssertions)
285
+
- Verify.Xunit for snapshot testing (useful for generated code verification)
288
286
- Comprehensive tests for generated code, serialization, and framework integration
287
+
- Follow Arrange-Act-Assert pattern for unit tests
288
+
- The tests should have same folder structure as the source code (e.g., with class `Ns1/Ns2/MyClass.cs` -> `Ns1/Ns2/MyCassTests/MyMethod.cs`)
289
+
- Create a separate test class/file for every public member (eg. for class `MyClass` with method `MyMethod` create `MyCassTests/MyMethod.cs`)
290
+
- If the tests requires a `CSharpCompilation` use base class `test/Thinktecture.Runtime.Extensions.SourceGenerator.Tests/CompilationTestBase.cs`
291
+
- When testing attributes, use real attributes, like `SmartEnumAttribute`, `ValueObjectAttribute`, `ComplexValueObjectAttribute`, `UnionAttribute`, `ObjectFactoryAttribute`, etc. Don't use fake attributes.
289
292
290
293
## Code Style
291
294
- Follow `.editorconfig` settings (especially in `src/.editorconfig`)
292
-
-**XML documentation required** for all publicly visible types and members (except source generator, test, and sample projects)
295
+
-**XML documentation required** for all publicly visible types and members (except source generator, analyzer, test, and sample projects)
293
296
- Multi-target framework support (net7.0 base, with EF Core version-specific projects)
294
-
-Use `dotnet format` to format the entire solution
297
+
-Don't use `#region`/`#endregion`
295
298
296
299
## Common Troubleshooting and Best Practices
297
300
@@ -301,14 +304,14 @@ The source generators follow a consistent pattern:
301
304
3.**Null handling**: For nullable key types, consider using `NullInFactoryMethodsYieldsNull` or `EmptyStringInFactoryMethodsYieldsNull` instead of throwing exceptions
302
305
4.**Immutability**: All members should be readonly (fields) or have no setter/private init (properties)
303
306
5.**Constructors**: Keep constructors private to enforce use of factory methods (`Create`, `TryCreate`)
304
-
6.**Smart Enum items**: Must be public static readonly/const - non-static properties won't be recognized as items
307
+
6.**Smart Enum items**: Must be public static readonly fields - non-static fields or properties won't be recognized as items
305
308
7.**Serialization**: Reference integration packages in the same project as your types for automatic code generation, or manually register converter factories
306
309
8.**Partial keyword**: Types must be marked `partial` for source generators to work
307
310
308
311
### Common Issues
309
312
1.**"Type must be partial"**: Add `partial` keyword to your class/struct declaration
3.**"Smart enum has no items"**: Ensure items are public static readonly/const fields or properties of the enum type
314
+
3.**"Smart enum has no items"**: Ensure items are public static readonly fields of the enum type
312
315
4.**"Custom key member implementation not found"**: When using `SkipKeyMember = true`, ensure you've implemented the key member with the correct name and type
313
316
5.**"Members disallowing default values must be required"**: Properties with `IDisallowDefaultValue` constraint must use `required` keyword or be initialized
314
317
6.**Serialization not working**: Ensure integration package is referenced, or manually register converters/formatters
@@ -332,3 +335,143 @@ The source generators follow a consistent pattern:
332
335
-**Result<T>**: Generic union for success/failure without exceptions (`Success(T Value)`, `Failure(string Error)`)
333
336
-**PartiallyKnownDate**: Regular union for dates with varying precision (year only, year/month, full date)
334
337
-**Jurisdiction**: Complex domain modeling combining unions and value objects
338
+
339
+
---
340
+
341
+
## Attribute Configuration Reference
342
+
343
+
This section lists constructor arguments and configurable properties for key attributes.
344
+
345
+
Notes:
346
+
- Defaults shown reflect runtime defaults from constructors or property getters.
347
+
- Some properties only take effect under certain conditions (see descriptions).
348
+
349
+
### Base Attributes (common configuration)
350
+
351
+
- ValueObjectAttributeBase (base for ValueObjectAttribute<TKey>, ComplexValueObjectAttribute)
352
+
- Properties:
353
+
- SkipFactoryMethods: bool — do not generate Create/TryCreate/Validate
0 commit comments