Primitive Obsession

Primitive Obsession (AKA StringlyTyped) means being obsessed with primitives. It is a Code Smell that degrades the quality of software.

Primitive Obsession is using primitive data types to represent domain ideasREADME.md

This code snippet, for example, shows Primitive Obsession:

int customerId = 42
          ``` [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          
          What's wrong with that? An `int` likely cannot *fully* represent a customer ID. An `int` can be negative or zero, but it's
          unlikely a customer ID can be. So, we have **constraints** on a customer ID. We can't _represent_ or _enforce_ those
          constraints on an `int`. [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          
          We can't be sure if it's been checked beforehand, so we need to check it every time we use it. Because it's a
          primitive, someone might've changed the value, so even if we're 100% sure we've checked it before, it still might need
          checking again.  [docs/site/Writerside/topics/discussions/Home.md](https://github.com/stevedunn/vogen/blob/main/docs/site/Writerside/topics/discussions/Home.md)
          
          So, we need some validation to ensure the **constraints** of a customer ID are met. Because it's in `int`, we can't be
          sure if it's been checked beforehand, so we need to check it every time we use it. Because it's a primitive,
          someone might've changed the value, so even if we're 100% sure we've checked it before, it still might need checking again.
          [docs/site/Writerside/topics/discussions/Home.md](https://github.com/stevedunn/vogen/blob/main/docs/site/Writerside/topics/discussions/Home.md)
          
          ### Value Objects to the Rescue
          
          The source generator generates value objects. Value objects help combat Primitive Obsession by wrapping simple
          primitives such as `int`, `string`, `double` etc. in a strongly-typed type. [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          
          Here's an example of a value object called `CustomerId`:
          
          ```csharp
          [ValueObject(typeof(int))]
          public partial struct CustomerId
          {
          }
          ``` [nuget-search-description.md](https://github.com/stevedunn/vogen/blob/main/docs/nuget-search-description.md)
          
          Instead of:
          
          ```csharp
          int customerId = 42;
          ``` [nuget-search-description.md](https://github.com/stevedunn/vogen/blob/main/docs/nuget-search-description.md)
          
          we have:
          
          ```cs
          var customerId = CustomerId.From(42);
          ``` [nuget-search-description.md](https://github.com/stevedunn/vogen/blob/main/docs/nuget-search-description.md)
          
          Here it is again with some validation:
          
          ``` cs
          public class CustomerId : ValueObject
          {
          private static Validation Validate(int value) =>
          value > 0 ? Validation.Ok : Validation.Invalid(); }
          ``` [nuget-search-description.md](https://github.com/stevedunn/vogen/blob/main/docs/nuget-search-description.md)
          
          ### The Source Generator and Value Objects
          
          The Source Generator generates code for things like creating the object and for performing equality.  [docs/nuget-readme.md](https://github.com/stevedunn/vogen/blob/main/docs/nuget-readme.md)
          
          The opinions are expressed as:
          
          * A value object (VO) is constructed via a factory method named `From`, e.g. `Age.From(12)` [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          * A VO is equatable (`Age.From(12) == Age.From(12)`) [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          * A VO, if validated, is validated with a static method named `Validate` that returns a `Validation` result [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          * Any validation that is not `Validation.Ok` results in a `ValueObjectValidationException` being thrown  [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          
          ### Performance
          
          One of the main goals of this project is to achieve **almost the same speed and memory performance as using
          primitives directly**. [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          
          Put another way, if your `decimal` primitive represents an Account Balance, then there is **extremely** low overhead
          of using an `AccountBalance` value object instead. [README.md](https://github.com/stevedunn/vogen/blob/main/README.md)
          

Top-Level Directory Explanations

samples/ - 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.

src/ - This directory contains the source code for the project. It includes the Vogen library itself, as well as any shared types and code fixers.

src/obj/ - This directory contains object files generated during the compilation process.

src/Vogen/ - This subdirectory contains the core Vogen library code. It includes subdirectories for diagnostics, extensions, generators, properties, rules, suppressors, templates, and binaries and object files.

tests/ - This directory contains unit tests and benchmarks for the project. It includes subdirectories for analyzer tests, consumer tests, snapshot tests, and Vogen benchmarks.

tests/AnalyzerTests/ - This subdirectory contains unit tests for the analyzer component of the Vogen library.

tests/ConsumerTests/ - This subdirectory contains unit tests for the consumer-side components of the Vogen library.

tests/SnapshotTests/ - This subdirectory contains snapshot tests, which test the output of the code generation and serialization components of the Vogen library.