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 new Age value object.
  • Equality: VOs are equatable. Two VOs are equal if they have the same value. For example, Age.From(12) == Age.From(12) is true.
  • Validation: VOs can be validated using a static method named Validate which returns a Validation result. If the validation fails, a ValueObjectValidationException 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 and TryParse 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


          ## 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.