|
1 |
| -# refine |
2 |
| -Type refinement using Roslyn source generation |
| 1 | +# Refine |
| 2 | +Refine is a source generator to help you design data types. |
| 3 | + |
| 4 | +- [avoid](https://refactoring.guru/smells/primitive-obsession) [primitive](https://wiki.c2.com/?PrimitiveObsession) [obsession](https://blog.ploeh.dk/2015/01/19/from-primitive-obsession-to-domain-modelling/) |
| 5 | +- "make illegal states unrepresentable" - [Yaron Minsky](https://youtu.be/-J8YyfrSwTk?si=3OBX5ANRFyi6TRGs) |
| 6 | + |
| 7 | +# Quick Start |
| 8 | + |
| 9 | +### 1. Add the NuGet |
| 10 | + |
| 11 | +```bash |
| 12 | +dotnet add package Refine |
| 13 | +dotnet add package Refine.Generators |
| 14 | +``` |
| 15 | + |
| 16 | +### 2. Decorate Your Class |
| 17 | + |
| 18 | +Add the `RefinedTypeAttribute` to a class and mark it as `partial`. |
| 19 | + |
| 20 | +```csharp |
| 21 | +using Refine; |
| 22 | + |
| 23 | +[RefinedType(typeof(string))] |
| 24 | +public partial class FullName; |
| 25 | +``` |
| 26 | + |
| 27 | +### 3. Transform and/or Validate |
| 28 | + |
| 29 | +```csharp |
| 30 | +using Refine; |
| 31 | + |
| 32 | +[RefinedType(typeof(string))] |
| 33 | +public partial class FullName |
| 34 | +{ |
| 35 | + private static string Transform(string value) => |
| 36 | + value?.Trim() ?? ""; |
| 37 | + |
| 38 | + private static bool TryValidate(string value) => |
| 39 | + !string.IsNullOrEmpty(value); |
| 40 | +} |
| 41 | +``` |
| 42 | + |
| 43 | +### 4. Instantiate |
| 44 | + |
| 45 | +```csharp |
| 46 | +string raw = "\tJames T. Kirk "; |
| 47 | +Console.WriteLine($"Raw: '{raw}'"); |
| 48 | + |
| 49 | +var refined = FullName.Create("\tJames T. Kirk "); |
| 50 | +Console.WriteLine($"Refined: '{refined.Value}'"); |
| 51 | +``` |
| 52 | +``` |
| 53 | +Raw: ' James T. Kirk ' |
| 54 | +Refined: 'James T. Kirk' |
| 55 | +``` |
| 56 | + |
| 57 | +### 5. Invalid States Are Unrepresentable |
| 58 | + |
| 59 | +```csharp |
| 60 | +var bad = FullName.Create(Environment.NewLine); |
| 61 | +``` |
| 62 | +throws `ArgumentException: Validation failed for the provided value.` |
| 63 | + |
| 64 | +# Deeper Dive |
| 65 | + |
| 66 | +1. Look at the [samples](./samples) |
| 67 | +2. Inspect the generated code |
| 68 | + - add `<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>` to your csproj |
| 69 | + - generated code will be under `obj/Debug/net8.0/generated/` |
| 70 | +3. More coming... |
0 commit comments