https://github.com/r-koubou/valueobjectgenerator
Generating code of value object by C# 9.0 Source Generator
https://github.com/r-koubou/valueobjectgenerator
csharp dotnet nuget roslyn source-generation
Last synced: 3 months ago
JSON representation
Generating code of value object by C# 9.0 Source Generator
- Host: GitHub
- URL: https://github.com/r-koubou/valueobjectgenerator
- Owner: r-koubou
- License: mit
- Created: 2021-01-16T23:04:38.000Z (over 5 years ago)
- Default Branch: main
- Last Pushed: 2022-01-19T19:09:09.000Z (over 4 years ago)
- Last Synced: 2025-10-10T05:44:31.652Z (8 months ago)
- Topics: csharp, dotnet, nuget, roslyn, source-generation
- Language: C#
- Homepage:
- Size: 164 KB
- Stars: 4
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# ValueObject Generator
Generating code of value object by C# 9.0 [Source Generator](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/)
Simple value objects can be created.
## Example
```c#
[ValueObject(typeof(int))]
public partial class Sample // 'struct' also supporting
{
// By default, the Validate method is defined and called from constructor
// If ValueOption.NonValidating is set, Validate method will not be defined
private static partial int Validate( int value ) => value;
}
```
will be generated to following
```c#
using System;
using System.Diagnostics.CodeAnalysis;
public partial struct Sample : IEquatable
{
public int Value { get; }
public Sample( int value )
{
Value = Validate( value );
}
private static partial int Validate( int value );
//
// Default ToString()
//
public override string ToString()
{
return Value.ToString() ?? "";
}
//----------------------------------------------------------------------
// Equality
//----------------------------------------------------------------------
public bool Equals( Sample other )
{
return Equals( Value, other.Value );
}
public override bool Equals( [AllowNull] object obj )
{
return obj is Sample other && Equals( other );
}
// HashCode
public override int GetHashCode() => Value.GetHashCode();
// Operator ==, !=
public static bool operator ==( Sample a, Sample b )
{
return a.Equals( b );
}
public static bool operator !=( Sample a, Sample b )
{
return !( a == b );
}
}
```
------
## ValueObject Attribute
`[ValueObject , [ValueName], [Option] ]`
### Type (*Required)
Type of value. use typeof syntax.
### ValueName
Applied to variable name (default: "Value")
e.g.
```c#
// Explicitly set the name of the value variable
[ValueObject(typeof(int), ValueName ="Point")]
public partial class Hp {}
```
will be generated to following
```c#
public partial class Hp : IEquatable
{
public int Point { get; } // variable name will be "Point" (default: "Value")
}
```
### Option
Flags to specify additional value specifications.
if set an`OptionFlags` value to ValueObjectAttribute, Generate code according to the flag value
### NonValidating
- Don't genetate `Valid` method
- Don't validate in constructor
Example
```c#
[ValueObject( typeof(int), Option = ValueOption.NonValidating)]
public partial class Sample {}
// *Validate method will not be defined
// private static partial int Validate( int value );
```
### Explicit
Add explicit operator
Example
```c#
[ValueObject( typeof(int), Option = ValueOption.Explicit )]
public partial class Sample {}
```
will be generated to following
```c#
public static explicit operator int( Sample x )
{
return x.Value;
}
public static explicit operator Sample( int value )
{
return new Sample( value );
}
```
### Implicit
Add implicit operator
Example
```c#
[ValueObject( typeof(int), Option = ValueOption.Implicit )]
public partial class Sample {}
```
will be generated to following
```c#
public static implicit operator int( Sample x )
{
return x.Value;
}
public static implicit operator Sample( int value )
{
return new Sample( value );
}
```
### Comparable
Add IComparable\ implementation
Example
```c#
[ValueObject( typeof(int), Option = ValueOption.Implicit )]
public partial class Sample {}
```
will be generated to following
```c#
public int CompareTo( Sample other )
{
if( ReferenceEquals( this, other ) )
{
return 0;
}
if( ReferenceEquals( null, other ) )
{
return 1;
}
return Value.CompareTo( other.Value );
}
```
### ToString
Add ToStringImpl Method for custom ToString implementarion
#### Default
```c#
public override string ToString()
{
return Value.ToString() ?? "";
}
```
Example
```c#
[ValueObject( typeof(int), Option = ValueOption.ToString )]
public partial class Sample {}
```
will be generated to following
```c#
private partial string ToStringImpl();
public override string ToString()
{
return ToStringImpl();
}
```
Default
```c#
public override string ToString()
{
return Value.ToString() ?? "";
}
```
------
## Available other attribute
Provides presets for validation. In many cases, it is exclusive to the Validate method.
### Value range
Example
```c#
[ValueObject(typeof(int))]
// Set an explicit range of values
[ValueRange(0, 9999)]
public partial class Count {}
```
will be generated to following
```c#
public partial class Count : IEquatable
{
public int Value { get; }
public Count( int value )
{
if( value < (0) || value > (9999) )
{
throw new ArgumentOutOfRangeException( $"(Count) Out of range : {value} (range:0 < 9999)" );
}
Value = value;
}
:
:
}
```
### Not negative
Example
```c#
[ValueObject(typeof(int))]
[NotNegative]
public partial class Count {}
```
will be generated to following
```c#
public partial class Count : IEquatable
{
public int Value { get; }
public Count( int value )
{
if( value < 0 )
{
throw new ArgumentException( $"(Count) value is negative : {value}" );
}
Value = value;
}
:
:
}
```
### Not empty
Example
```c#
[ValueObject(typeof(string))]
[NotEmpty]
public partial class Name {}
```
will be generated to following
```c#
public partial class Name : IEquatable
{
public string Value { get; }
public Name( string value )
{
if( string.IsNullOrEmpty( value ) || value.Trim().Length == 0 )
{
throw new ArgumentException( $"(Name) value is empty" );
}
Value = value;
}
}
```
Note: if type is string, use string.IsNullOrEmpty, Trim. Otherwise use Linq.Any()
e.g.
```c#
[ValueObject(typeof(string[]))]
[NotEmpty]
public partial class Names {}
```
will be generated to following
```c#
public partial class Names : IEquatable
{
public string[] Value { get; }
public Names( string[] value )
{
if( !value.Any() )
{
throw new ArgumentException( $"(Names) value is empty" );
}
Value = value;
}
:
:
}
```
If you do not want to treat a string with only whitespace characters as Empty, set the **ExcludeWhiteSpace** argument to true.
```c#
[ValueObject(typeof(string))]
[NotEmpty(ExcludeWhiteSpace=true)]
public partial class Name {}
```
will be generated to following
```c#
public partial class Name : IEquatable
{
public string Value { get; }
public Name( string value )
{
if( string.IsNullOrEmpty( value ) )
{
throw new ArgumentException( $"(Name) value is empty" );
}
Value = value;
}
:
:
}
```