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