Skip to content

Commit f4eaea4

Browse files
Update README.md
1 parent d9844f2 commit f4eaea4

1 file changed

Lines changed: 65 additions & 3 deletions

File tree

README.md

Lines changed: 65 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,71 @@
11
# WrapperValueObject
22

3-
A .NET source generator for creating simple value objects without too much boilerplate for `Equals`, `GetHashCode` and operators overloads/implementations.
3+
![Build](https://github.com/martinothamar/WrapperValueObject/workflows/Build/badge.svg)
4+
[![NuGet](https://img.shields.io/nuget/v/WrapperValueObject.Generator.svg)](https://www.nuget.org/packages/WrapperValueObject.Generator/)
45

5-
## Example
6+
A .NET source generator for creating
7+
* Simple value objects wrapping other type(s), without the hassle of manual `Equals`/`GetHashCode`
8+
* Value objects wrapping math primitives
9+
* I.e. `[WrapperValueObject(typeof(int))] partial readonly struct MeterLength` - the type is implicitly castable to `int`, and you can create your own math operations
10+
* Strongly typed ID's
11+
* Similar to F# `type ProductId = ProductId of Guid`, here it becomes `[WrapperValueObject] partial readonly struct ProductId`
12+
13+
Note that record type feature for structs is planned for C# 10, in which cases some of the
14+
use cases this library supports will be easier to achieve without this libray.
15+
16+
## Installation
17+
18+
Add to your project file:
19+
20+
```xml
21+
<PackageReference Include="WrapperValueObject.Generator" Version="0.0.1-alpha04">
22+
<PrivateAssets>all</PrivateAssets>
23+
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
24+
</PackageReference>
25+
```
26+
27+
Or install via CLI
28+
29+
```sh
30+
dotnet add package WrapperValueObject.Generator --version 0.0.1-alpha04
31+
```
32+
33+
## Usage
634

735
1. Use the attribute to specify the underlying type.
836
2. Declare the struct or class with the `partial` keyword. (and does not support nested types)
937

38+
### Simple example
39+
40+
```csharp
41+
[WrapperValueObject(typeof(int))]
42+
public readonly partial struct MeterLength
43+
{
44+
public static implicit operator CentimeterLength(MeterLength meter) => meter.Value * 100;
45+
}
46+
47+
[WrapperValueObject(typeof(int))]
48+
public readonly partial struct CentimeterLength
49+
{
50+
public static implicit operator MeterLength(CentimeterLength centiMeter) => centiMeter / 100;
51+
}
52+
53+
MeterLength meters = 2;
54+
55+
CentimeterLength centiMeters = meters;
56+
57+
Assert.Equal(200, (int)centiMeters);
58+
```
59+
60+
### Full example
61+
1062
```csharp
1163
using System;
1264
using System.Diagnostics;
1365

1466
namespace WrapperValueObject.TestConsole
1567
{
16-
[WrapperValueObject(typeof(Guid))]
68+
[WrapperValueObject] // Is Guid by default
1769
public readonly partial struct MatchId
1870
{
1971
public static MatchId New() => Guid.NewGuid();
@@ -63,3 +115,13 @@ namespace WrapperValueObject.TestConsole
63115
}
64116
}
65117
```
118+
119+
## TODO/under consideration
120+
121+
Further development on this PoC was prompted by this discussion: https://github.com/ironcev/awesome-roslyn/issues/17
122+
123+
* Replace one generic attribute (WrapperValueObject) with two (or more) that cleary identify the usecase. E.g. StronglyTypedIdAttribute, ImmutableStructAttribute, ...
124+
* Support everything that StronglyTypedId supports (e.g. optional generation of JSON converters).
125+
* Bring the documentation to the same level as in the StronglyTypedId project.
126+
* Write tests.
127+
* Create Nuget package.

0 commit comments

Comments
 (0)