Value Object Implementation
Vogen is a library that automatically generates code for value objects. Value objects represent a small object whose equality is based on value and not identity.
Key Concepts
- Value Objects (VOs): VOs are immutable objects that wrap primitive types like
int
,string
,double
, etc. They provide strong typing and help prevent accidental misuse of primitives. - Factories: VOs are constructed using factory methods named
From
. For example,Age.From(12)
creates a newAge
value object. - Equality: VOs are equatable. Two VOs are equal if they have the same value. For example,
Age.From(12) == Age.From(12)
istrue
. - Validation: VOs can be validated using a static method named
Validate
which returns aValidation
result. If the validation fails, aValueObjectValidationException
is thrown. - Instances: VOs can have pre-set instances that bypass validation and normalization. This is useful for representing known values or values that users cannot create.
Example Usage
To create a value object, decorate a partial type with the ValueObject
attribute:
[ValueObject]
public partial struct CustomerId { }
To create a new instance, use the From
method:
var customerId = CustomerId.From(42);
Using Value Objects in Code
Instead of using primitives like int
, use value objects to represent domain concepts. For example, instead of int customerId = 42
, use var customerId = CustomerId.From(42);
Validation and Exception Handling
The From
method throws a ValueObjectValidationException
if validation fails. You can also use the TryFrom
method, which returns a ValueObjectOrError
object or a boolean indicating success and an out parameter.
Generating Value Objects
Vogen generates code for value objects using a source generator. The generator creates:
- Factory methods (
From
) - Equality methods (
operator ==
,operator !=
) - Validation methods (
Validate
) - Conversion methods (including serialization support)
- Debug attributes
Customization Options
The ValueObject
attribute allows you to customize the generated code:
- Conversions: Control the type of conversion code generated (e.g., type converters, serialization).
- Throws: Specify the type of exception thrown when validation fails.
- Customizations: Enable various customization options like generating
GetHashCode
,ToString
, and other methods. - DeserializationStrictness: Control how strict deserialization should be.
- DebuggerAttributeGeneration: Specify the level of debug attributes generated.
- ComparisonGeneration: Customize the generated comparison code (e.g.,
IComparable
,IEquatable
). - StringComparersGeneration: Specify the generation of string comparison methods.
- CastOperator: Control the generation of cast operators between the value object and the underlying primitive.
- ParsableForStrings: Specify the generation of
IParsable
methods for strings. - ParsableForPrimitives: Specify the generation of
Parse
andTryParse
methods for primitives. - TryFromGeneration: Control the generation of
TryFrom
methods. - IsInitializedMethodGeneration: Specify the generation of an
IsInitialized
method. - PrimitiveEqualityGeneration: Control the generation of operators for comparing the value object to the underlying primitive.
Resources
- Vogen GitHub Repository: https://github.com/stevedunn/vogen/
- Vogen Documentation: tree/master/docs/site
## Top-Level Directory Explanations
<a class='local-link directory-link' data-ref="samples/" href="#samples/">samples/</a> - This directory contains example projects that demonstrate the usage of the Vogen library. Each subdirectory represents a different example, and contains the necessary files and configurations for that example.
<a class='local-link directory-link' data-ref="src/" href="#src/">src/</a> - This directory contains the source code for the project. It includes the Vogen library itself, as well as any shared types and code fixers.
<a class='local-link directory-link' data-ref="src/obj/" href="#src/obj/">src/obj/</a> - This directory contains object files generated during the compilation process.
<a class='local-link directory-link' data-ref="src/Vogen/" href="#src/Vogen/">src/Vogen/</a> - This subdirectory contains the core Vogen library code. It includes subdirectories for diagnostics, extensions, generators, properties, rules, suppressors, templates, and binaries and object files.
<a class='local-link directory-link' data-ref="tests/" href="#tests/">tests/</a> - This directory contains unit tests and benchmarks for the project. It includes subdirectories for analyzer tests, consumer tests, snapshot tests, and Vogen benchmarks.
<a class='local-link directory-link' data-ref="tests/AnalyzerTests/" href="#tests/AnalyzerTests/">tests/AnalyzerTests/</a> - This subdirectory contains unit tests for the analyzer component of the Vogen library.
<a class='local-link directory-link' data-ref="tests/ConsumerTests/" href="#tests/ConsumerTests/">tests/ConsumerTests/</a> - This subdirectory contains unit tests for the consumer-side components of the Vogen library.
<a class='local-link directory-link' data-ref="tests/SnapshotTests/" href="#tests/SnapshotTests/">tests/SnapshotTests/</a> - This subdirectory contains snapshot tests, which test the output of the code generation and serialization components of the Vogen library.
<a class='local-link directory-link' data-ref="tests/Vogen.Benchmarks/" href="#tests/Vogen.Benchmarks/">tests/Vogen.Benchmarks/</a> - This subdirectory contains benchmarks for the performance of the Vogen library.