diff --git a/docs/site/Writerside/topics/how-to/conversion-mechanisms.md b/docs/site/Writerside/topics/how-to/conversion-mechanisms.md
index dc43b733b8..abce224062 100644
--- a/docs/site/Writerside/topics/how-to/conversion-mechanisms.md
+++ b/docs/site/Writerside/topics/how-to/conversion-mechanisms.md
@@ -339,7 +339,7 @@ public class Customer
{
[BsonId]
public CustomerId Id { get; set; }
-
+
public string Name { get; set; }
}
@@ -347,6 +347,26 @@ public class Customer
var customer = collection.Find(c => c.Id == customerId).FirstOrDefault();
```
+**Registration Options:**
+
+By default, Vogen generates a static class with a static constructor that automatically registers BSON serializers.
+If you need to configure BSON before registration (e.g., custom serializers, conventions), use:
+
+```c#
+[assembly: VogenDefaults(
+ conversions: Conversions.Bson,
+ customizations: Customizations.ManuallyRegisterBsonSerializers)]
+
+// Now you control when registration happens:
+// 1. Configure BSON as needed
+BsonSerializer.RegisterSerializer(new CustomSerializer());
+
+// 2. Then register Vogen serializers
+BsonSerializationRegisterFor[YourProjectName].TryRegister();
+```
+
+See [MongoDB Integration](MongoIntegrationHowTo.md) for details.
+
### MessagePack
```c#
diff --git a/docs/site/Writerside/topics/reference/Configuration.md b/docs/site/Writerside/topics/reference/Configuration.md
index 99e35467cf..856180c56d 100644
--- a/docs/site/Writerside/topics/reference/Configuration.md
+++ b/docs/site/Writerside/topics/reference/Configuration.md
@@ -20,7 +20,11 @@ Most values are present in both `ValueObject` and `VogenDefaults`. The parameter
* `underlyingType`—the type of the primitive that is being wrapped—defaults to `int`
* `conversions` - specified what conversion code is generated - defaults to `Conversions.Default` which generates type converters and a converter to handle serialization using System.Text.Json
* `throws` = specifies the type of exception thrown when validation fails—defaults to `ValueObjectValidationException`
-* `customizations`—simple customization switches—defaults to `Customizations.None`,
+* `customizations`—simple customization switches—defaults to `Customizations.None`. Available flags:
+ * `Customizations.TreatNumberAsStringInSystemTextJson` - serialize numbers as strings in System.Text.Json (obsolete on .NET 5+)
+ * `Customizations.AddFactoryMethodForGuids` - adds a `FromNewGuid()` factory method for GUID value objects
+ * `Customizations.GenerateLinqPadToDump` - generates a `ToDump()` method for LinqPad
+ * `Customizations.ManuallyRegisterBsonSerializers` - generates BSON registration as a `TryRegister()` method without a static constructor, allowing control over registration timing,
* `deserializationStrictness` - specifies how strict deserialization is, e.g. should your `Validate` method be called, or should pre-defined instances that otherwise invalid be allowed - defaults to `DeserializationStrictness.AllowValidAndKnownInstances`
* `debuggerAttributes` - specifies the level that debug attributes are written as some IDEs don't support all of them, e.g., Rider - defaults to `DebuggerAttributeGeneration.Full` which generates `DebuggerDisplay` and a debugger proxy type for IDEs that support them
* `comparison`—species which comparison code is generated—defaults to `ComparisonGeneration.UseUnderlying` which hoists any `IComparable` implementations from the primitive
diff --git a/docs/site/Writerside/topics/reference/FAQ.md b/docs/site/Writerside/topics/reference/FAQ.md
index 965122826a..882ab3ee11 100644
--- a/docs/site/Writerside/topics/reference/FAQ.md
+++ b/docs/site/Writerside/topics/reference/FAQ.md
@@ -451,7 +451,30 @@ var newCustomerId = CustomerId.FromNewGuid();
```
> To customize the generation of Guids, please see [this tutorial](Working-with-IDs.md)
->
+>
+
+## How do I control when BSON serializers are registered?
+
+By default, Vogen generates a static class with a static constructor that automatically registers BSON serializers when first accessed.
+If you need to run BSON configuration before registration (e.g., set up custom conventions, configure serializers), use:
+
+```c#
+[assembly: VogenDefaults(
+ customizations: Customizations.ManuallyRegisterBsonSerializers)]
+```
+
+This generates a `TryRegister()` method without a static constructor, giving you full control:
+
+```c#
+// 1. Configure BSON as needed
+BsonSerializer.RegisterSerializer(new MyCustomSerializer());
+ConventionRegistry.Register("MyConventions", new ConventionPack { ... }, _ => true);
+
+// 2. Then register Vogen-generated serializers
+BsonSerializationRegisterFor[YourProjectName].TryRegister();
+```
+
+See [MongoDB Integration](MongoIntegrationHowTo.md) for more details.
## Can I use value objects instead of primitives as parameters in Blazor pages and components?
diff --git a/docs/site/Writerside/topics/reference/MongoIntegrationHowTo.md b/docs/site/Writerside/topics/reference/MongoIntegrationHowTo.md
index d3b34883a3..3634622ee9 100644
--- a/docs/site/Writerside/topics/reference/MongoIntegrationHowTo.md
+++ b/docs/site/Writerside/topics/reference/MongoIntegrationHowTo.md
@@ -14,7 +14,22 @@ public partial class Name
Now that the serializers are generated, you now need to register them.
Vogen generates a static class named `RegisterBsonSerializersFor[NameOfProject]`.
-This static class has a static method named `TryRegister`, which registers the serializers if they're not already registered, e.g.:
+
+By default, this class has a static constructor that automatically registers all BSON serializers when first accessed.
+However, if you need to run BSON configuration before the serializers are registered, you can use the `ManuallyRegisterBsonSerializers` customization:
+
+```c#
+[assembly: VogenDefaults(customizations: Customizations.ManuallyRegisterBsonSerializers)]
+```
+
+With this flag set, Vogen generates a `TryRegister()` method without a static constructor, allowing you to control when registration occurs:
+
+```C#
+// Call this manually after any BSON configuration
+BsonSerializationRegisterFor[YourProjectName].TryRegister();
+```
+
+Without the flag, the static constructor automatically calls code like:
```C#
BsonSerializer.TryRegisterSerializer(new CustomerIdBsonSerializer());
@@ -54,4 +69,8 @@ BsonSerializationRegisterForVogen_Examples.TryRegister();
(_replace `Vogen_Examples` with the name of *your* project_)
+> **Note:** By default, the static class has a static constructor that automatically registers serializers when first accessed.
+> If you need control over when registration happens (e.g., to configure BSON first), use the `Customizations.ManuallyRegisterBsonSerializers` flag
+> to generate only the `TryRegister()` method without the static constructor.
+
Next, it adds a bunch of `Person` objects to the database, each containing value objects representing age and name, and then reads them back.
\ No newline at end of file
diff --git a/src/Vogen.SharedTypes/Customizations.cs b/src/Vogen.SharedTypes/Customizations.cs
index bf3e5e6a74..eee3a7f6b6 100644
--- a/src/Vogen.SharedTypes/Customizations.cs
+++ b/src/Vogen.SharedTypes/Customizations.cs
@@ -36,5 +36,13 @@ public enum Customizations
///
/// Generate ToDump for LinqPad
///
- GenerateLinqPadToDump = 1 << 2
+ GenerateLinqPadToDump = 1 << 2,
+
+ ///
+ /// Manually register BSON registrations. By default, Vogen creates a static class with a static constructor that registers
+ /// all BSON serializers. However, you might want to run BSON configuration before this.
+ /// This flag tells Vogen to create a `TryRegister` method on a class named `BsonSerializationRegisterFor[YourAssemblyName]`
+ /// as opposed to a static constructor
+ ///
+ ManuallyRegisterBsonSerializers = 1 << 3
}
\ No newline at end of file
diff --git a/src/Vogen/GenerateCodeForBsonSerializers.cs b/src/Vogen/GenerateCodeForBsonSerializers.cs
index 4eb5e17fa3..1968a0e756 100644
--- a/src/Vogen/GenerateCodeForBsonSerializers.cs
+++ b/src/Vogen/GenerateCodeForBsonSerializers.cs
@@ -9,7 +9,7 @@ namespace Vogen;
internal class GenerateCodeForBsonSerializers
{
private const string _nameSuffix = "BsonSerializer";
-
+
///
/// For each value object that has a BSON conversion attribute, write a separate file with a serializer,
/// with a class name of '[WrapperName]BsonSerializer', and a filename of '[NameSpace].[WrapperName]_bson.g.cs'
@@ -17,7 +17,11 @@ internal class GenerateCodeForBsonSerializers
///
///
///
- public static void GenerateForApplicableValueObjects(SourceProductionContext context, Compilation compilation, List workItems)
+ ///
+ public static void GenerateForApplicableValueObjects(SourceProductionContext context,
+ Compilation compilation,
+ List workItems,
+ Customizations? customizations)
{
if (!compilation.IsAtLeastCSharp12())
{
@@ -35,7 +39,7 @@ public static void GenerateForApplicableValueObjects(SourceProductionContext con
Util.AddSourceToContext(filename, context, Util.FormatSource(eachGenerated));
}
- WriteRegistration(applicableWrappers, compilation, context);
+ WriteRegistration(applicableWrappers, compilation, context, customizations);
}
///
@@ -131,7 +135,10 @@ string GenerateSerializers()
}
}
- private static void WriteRegistration(List items, Compilation compilation, SourceProductionContext context)
+ private static void WriteRegistration(List items,
+ Compilation compilation,
+ SourceProductionContext context,
+ Customizations? customizations)
{
if (items.Count == 0)
{
@@ -140,20 +147,7 @@ private static void WriteRegistration(List items, Compilation compil
var classNameForRegistering = ClassNameForRegistering();
- string source =
- $$"""
- {{GeneratedCodeSegments.Preamble}}
-
- public static class {{classNameForRegistering}}
- {
- static {{classNameForRegistering}}()
- {
- {{TextForEachRegisterCall(items)}}
- }
-
- public static void TryRegister() { }
- }
- """;
+ var source = GenerateRegistrationSource();
Util.AddSourceToContext(classNameForRegistering, context, Util.FormatSource(source));
return;
@@ -170,6 +164,37 @@ string ClassNameForRegistering()
return s;
}
+
+ string GenerateRegistrationSource()
+ {
+ bool manual = customizations is not null && customizations.Value.HasFlag(Customizations.ManuallyRegisterBsonSerializers);
+
+ return manual
+ ? $$"""
+ {{GeneratedCodeSegments.Preamble}}
+
+ public static class {{classNameForRegistering}}
+ {
+ public static void TryRegister()
+ {
+ {{TextForEachRegisterCall(items)}}
+ }
+ }
+ """
+ : $$"""
+ {{GeneratedCodeSegments.Preamble}}
+
+ public static class {{classNameForRegistering}}
+ {
+ static {{classNameForRegistering}}()
+ {
+ {{TextForEachRegisterCall(items)}}
+ }
+
+ public static void TryRegister() { }
+ }
+ """;
+ }
}
private static string TextForEachRegisterCall(List wrappers)
diff --git a/src/Vogen/ValueObjectGenerator.cs b/src/Vogen/ValueObjectGenerator.cs
index 61856f8798..2117039250 100644
--- a/src/Vogen/ValueObjectGenerator.cs
+++ b/src/Vogen/ValueObjectGenerator.cs
@@ -136,7 +136,7 @@ private static void Execute(
GenerateCodeForMessagePack.GenerateForApplicableValueObjects(spc, compilation, workItems);
GenerateCodeForMessagePack.GenerateForMarkerClasses(spc, markerClasses);
- GenerateCodeForBsonSerializers.GenerateForApplicableValueObjects(spc, compilation, workItems);
+ GenerateCodeForBsonSerializers.GenerateForApplicableValueObjects(spc, compilation, workItems, globalConfig?.Customizations);
GenerateCodeForBsonSerializers.GenerateForMarkerClasses(spc, markerClasses);
GenerateCodeForOrleansSerializers.WriteIfNeeded(spc, workItems);
diff --git a/tests/SnapshotTests/BsonSerializationGeneration/BsonSerializationGenerationTests.cs b/tests/SnapshotTests/BsonSerializationGeneration/BsonSerializationGenerationTests.cs
index bbe8e8a48a..316e24f76b 100644
--- a/tests/SnapshotTests/BsonSerializationGeneration/BsonSerializationGenerationTests.cs
+++ b/tests/SnapshotTests/BsonSerializationGeneration/BsonSerializationGenerationTests.cs
@@ -29,6 +29,29 @@ public partial struct Name;
.RunOn(TargetFramework.Net8_0);
}
+ [Fact]
+ public async Task Writes_bson_serializers_but_manually_register_the_serializers()
+ {
+ var source = """
+ using System;
+ using Vogen;
+
+ [assembly: VogenDefaults(conversions: Conversions.Bson, customizations: Customizations.ManuallyRegisterBsonSerializers)]
+
+ namespace Whatever;
+ [ValueObject]
+ public partial struct Age;
+
+ [ValueObject]
+ public partial struct Name;
+ """;
+
+ await new SnapshotRunner()
+ .WithSource(source)
+ .IgnoreInitialCompilationErrors()
+ .RunOn(TargetFramework.Net8_0);
+ }
+
[Fact]
public async Task Escapes_namespaces()
{
diff --git a/tests/SnapshotTests/BsonSerializationGeneration/snapshots/snap-v8.0/BsonSerializationGenerationTests.Writes_bson_serializers_but_manually_register_the_serializers.verified.txt b/tests/SnapshotTests/BsonSerializationGeneration/snapshots/snap-v8.0/BsonSerializationGenerationTests.Writes_bson_serializers_but_manually_register_the_serializers.verified.txt
new file mode 100644
index 0000000000..d21fe57a4e
--- /dev/null
+++ b/tests/SnapshotTests/BsonSerializationGeneration/snapshots/snap-v8.0/BsonSerializationGenerationTests.Writes_bson_serializers_but_manually_register_the_serializers.verified.txt
@@ -0,0 +1,1288 @@
+[
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+// Suppress warnings about CS8767 : Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+#pragma warning disable CS8767
+namespace Whatever;
+public partial class AgeBsonSerializer : global::MongoDB.Bson.Serialization.Serializers.SerializerBase
+{
+ private readonly global::MongoDB.Bson.Serialization.IBsonSerializer _serializer = global::MongoDB.Bson.Serialization.BsonSerializer.LookupSerializer();
+ public override Whatever.Age Deserialize(global::MongoDB.Bson.Serialization.BsonDeserializationContext context, global::MongoDB.Bson.Serialization.BsonDeserializationArgs args)
+ {
+ var newArgs = new global::MongoDB.Bson.Serialization.BsonDeserializationArgs
+ {
+ NominalType = typeof(global::System.Int32)
+ };
+ return Deserialize(_serializer.Deserialize(context, newArgs));
+ }
+
+ public override void Serialize(global::MongoDB.Bson.Serialization.BsonSerializationContext context, global::MongoDB.Bson.Serialization.BsonSerializationArgs args, Whatever.Age value) => _serializer.Serialize(context, args, value.Value);
+ static Whatever.Age Deserialize(global::System.Int32 value) => UnsafeDeserialize(default, value);
+ [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")]
+ static extern Whatever.Age UnsafeDeserialize(Whatever.Age @this, global::System.Int32 value);
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+// Suppress warnings about CS8767 : Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+#pragma warning disable CS8767
+namespace Whatever;
+public partial class NameBsonSerializer : global::MongoDB.Bson.Serialization.Serializers.SerializerBase
+{
+ private readonly global::MongoDB.Bson.Serialization.IBsonSerializer _serializer = global::MongoDB.Bson.Serialization.BsonSerializer.LookupSerializer();
+ public override Whatever.Name Deserialize(global::MongoDB.Bson.Serialization.BsonDeserializationContext context, global::MongoDB.Bson.Serialization.BsonDeserializationArgs args)
+ {
+ var newArgs = new global::MongoDB.Bson.Serialization.BsonDeserializationArgs
+ {
+ NominalType = typeof(global::System.String)
+ };
+ return Deserialize(_serializer.Deserialize(context, newArgs));
+ }
+
+ public override void Serialize(global::MongoDB.Bson.Serialization.BsonSerializationContext context, global::MongoDB.Bson.Serialization.BsonSerializationArgs args, Whatever.Name value) => _serializer.Serialize(context, args, value.Value);
+ static Whatever.Name Deserialize(global::System.String value) => UnsafeDeserialize(default, value);
+ [global::System.Runtime.CompilerServices.UnsafeAccessor(global::System.Runtime.CompilerServices.UnsafeAccessorKind.StaticMethod, Name = "__Deserialize")]
+ static extern Whatever.Name UnsafeDeserialize(Whatever.Name @this, global::System.String value);
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+// Suppress warnings about CS8767 : Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+#pragma warning disable CS8767
+public static class BsonSerializationRegisterForgenerator
+{
+ public static void TryRegister()
+ {
+ global::MongoDB.Bson.Serialization.BsonSerializer.TryRegisterSerializer(new Whatever.AgeBsonSerializer());
+ global::MongoDB.Bson.Serialization.BsonSerializer.TryRegisterSerializer(new Whatever.NameBsonSerializer());
+ }
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+// Suppress warnings about CS8767 : Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+#pragma warning disable CS8767
+namespace generator
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ public class VogenTypesFactory : global::System.Text.Json.Serialization.JsonConverterFactory
+ {
+ public VogenTypesFactory()
+ {
+ }
+
+ private static readonly global::System.Collections.Generic.Dictionary> _lookup = new global::System.Collections.Generic.Dictionary>
+ {
+ };
+ public override bool CanConvert(global::System.Type typeToConvert) => _lookup.ContainsKey(typeToConvert);
+ public override global::System.Text.Json.Serialization.JsonConverter CreateConverter(global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options) => _lookup[typeToConvert].Value;
+ }
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+// Suppress warnings about CS8767 : Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+#pragma warning disable CS8767
+namespace Whatever
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(AgeDebugView))]
+ [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: global::System.Int32, Value = { _value }")]
+ // ReSharper disable once UnusedType.Global
+ public partial struct Age : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.ISpanParsable, global::System.IUtf8SpanParsable, global::System.IFormattable, global::System.ISpanFormattable, global::System.IUtf8SpanFormattable, global::System.IConvertible
+ {
+#if DEBUG
+private readonly global::System.Diagnostics.StackTrace _stackTrace = null!;
+#endif
+#if !VOGEN_NO_VALIDATION
+ private readonly global::System.Boolean _isInitialized;
+#endif
+ private readonly global::System.Int32 _value;
+ ///
+ /// Gets the underlying value if set, otherwise a is thrown.
+ ///
+ public readonly global::System.Int32 Value
+ {
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ EnsureInitialized();
+ return _value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
+ public Age()
+ {
+#if DEBUG
+ _stackTrace = new global::System.Diagnostics.StackTrace();
+#endif
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = false;
+#endif
+ _value = default;
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ private Age(global::System.Int32 value)
+ {
+ _value = value;
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = true;
+#endif
+#if DEBUG
+ _stackTrace = null;
+#endif
+ }
+
+ ///
+ /// Builds an instance from the provided underlying type.
+ ///
+ /// The underlying type.
+ /// An instance of this type.
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ public static Age From(global::System.Int32 value)
+ {
+ return new Age(value);
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying type.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, false will be returned.
+ ///
+ /// The underlying type.
+ /// An instance of the value object.
+ /// True if the value object can be built, otherwise false.
+ public static bool TryFrom(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ global::System.Int32 value,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out Age vo)
+ {
+ vo = new Age(value);
+ return true;
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying value.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, an error will be returned.
+ ///
+ /// The primitive value.
+ /// A containing either the value object, or an error.
+ public static global::Vogen.ValueObjectOrError TryFrom(global::System.Int32 value)
+ {
+ return new global::Vogen.ValueObjectOrError(new Age(value));
+ }
+
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+#if VOGEN_NO_VALIDATION
+#pragma warning disable CS8775
+ public readonly bool IsInitialized() => true;
+#pragma warning restore CS8775
+#else
+ public readonly bool IsInitialized() => _isInitialized;
+#endif
+ public static explicit operator Age(global::System.Int32 value) => From(value);
+ public static explicit operator global::System.Int32(Age value) => value.Value;
+ // only called internally when something has been deserialized into
+ // its primitive type.
+ private static Age __Deserialize(global::System.Int32 value)
+ {
+ return new Age(value);
+ }
+
+ public readonly global::System.Boolean Equals(Age other)
+ {
+ // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals.
+ // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type.
+ if (!IsInitialized() || !other.IsInitialized())
+ return false;
+ return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value);
+ }
+
+ public global::System.Boolean Equals(Age other, global::System.Collections.Generic.IEqualityComparer comparer)
+ {
+ return comparer.Equals(this, other);
+ }
+
+ public readonly global::System.Boolean Equals(global::System.Int32 primitive)
+ {
+ return Value.Equals(primitive);
+ }
+
+ public readonly override global::System.Boolean Equals(global::System.Object obj)
+ {
+ return obj is Age && Equals((Age)obj);
+ }
+
+ public static global::System.Boolean operator ==(Age left, Age right) => left.Equals(right);
+ public static global::System.Boolean operator !=(Age left, Age right) => !(left == right);
+ public static global::System.Boolean operator ==(Age left, global::System.Int32 right) => left.Value.Equals(right);
+ public static global::System.Boolean operator ==(global::System.Int32 left, Age right) => right.Value.Equals(left);
+ public static global::System.Boolean operator !=(global::System.Int32 left, Age right) => !(left == right);
+ public static global::System.Boolean operator !=(Age left, global::System.Int32 right) => !(left == right);
+ public int CompareTo(Age other) => Value.CompareTo(other.Value);
+ public int CompareTo(object other)
+ {
+ if (other is null)
+ return 1;
+ if (other is Age x)
+ return CompareTo(x);
+ ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type Age", nameof(other));
+ return 0;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(utf8Text, style, provider, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(utf8Text, provider, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(global::System.ReadOnlySpan utf8Text,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(utf8Text, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(s, style, provider, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(s, provider, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(global::System.ReadOnlySpan s,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(s, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(s, style, provider, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(string s, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(s, provider, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// True if the value could a) be parsed by the underlying type, and b) passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(string s,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ out Age result)
+ {
+ if (global::System.Int32.TryParse(s, out var __v))
+ {
+ result = new Age(__v);
+ return true;
+ }
+
+ result = default;
+ return false;
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(global::System.ReadOnlySpan utf8Text, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider)
+ {
+ var r = global::System.Int32.Parse(utf8Text, style, provider);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(global::System.ReadOnlySpan utf8Text, global::System.IFormatProvider provider)
+ {
+ var r = global::System.Int32.Parse(utf8Text, provider);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(global::System.ReadOnlySpan s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider)
+ {
+ var r = global::System.Int32.Parse(s, style, provider);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(global::System.ReadOnlySpan s, global::System.IFormatProvider provider)
+ {
+ var r = global::System.Int32.Parse(s, provider);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(string s)
+ {
+ var r = global::System.Int32.Parse(s);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(string s, global::System.Globalization.NumberStyles style)
+ {
+ var r = global::System.Int32.Parse(s, style);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(string s, global::System.Globalization.NumberStyles style, global::System.IFormatProvider provider)
+ {
+ var r = global::System.Int32.Parse(s, style, provider);
+ return From(r);
+ }
+
+ ///
+ ///
+ ///
+ ///
+ /// The value created by calling the Parse method on the primitive.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Age Parse(string s, global::System.IFormatProvider provider)
+ {
+ var r = global::System.Int32.Parse(s, provider);
+ return From(r);
+ }
+
+#nullable disable
+ ///
+ public string ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format, global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? Value.ToString(format, provider) : "[UNINITIALIZED]";
+ }
+
+ ///
+ public bool TryFormat(global::System.Span destination, out int charsWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider)
+ {
+ charsWritten = default;
+ return IsInitialized() ? Value.TryFormat(destination, out charsWritten, format, provider) : true;
+ }
+
+ ///
+ public bool TryFormat(global::System.Span utf8Destination, out int bytesWritten, [System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] global::System.ReadOnlySpan format, global::System.IFormatProvider provider)
+ {
+ bytesWritten = default;
+ return IsInitialized() ? Value.TryFormat(utf8Destination, out bytesWritten, format, provider) : true;
+ }
+
+#nullable restore
+#nullable disable
+ ///
+ public System.TypeCode GetTypeCode()
+ {
+ return IsInitialized() ? Value.GetTypeCode() : default;
+ }
+
+ ///
+ bool System.IConvertible.ToBoolean(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToBoolean(provider) : default;
+ }
+
+ ///
+ byte System.IConvertible.ToByte(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToByte(provider) : default;
+ }
+
+ ///
+ char System.IConvertible.ToChar(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToChar(provider) : default;
+ }
+
+ ///
+ System.DateTime System.IConvertible.ToDateTime(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToDateTime(provider) : default;
+ }
+
+ ///
+ decimal System.IConvertible.ToDecimal(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToDecimal(provider) : default;
+ }
+
+ ///
+ double System.IConvertible.ToDouble(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToDouble(provider) : default;
+ }
+
+ ///
+ short System.IConvertible.ToInt16(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToInt16(provider) : default;
+ }
+
+ ///
+ int System.IConvertible.ToInt32(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToInt32(provider) : default;
+ }
+
+ ///
+ long System.IConvertible.ToInt64(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToInt64(provider) : default;
+ }
+
+ ///
+ sbyte System.IConvertible.ToSByte(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToSByte(provider) : default;
+ }
+
+ ///
+ float System.IConvertible.ToSingle(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToSingle(provider) : default;
+ }
+
+ ///
+ object System.IConvertible.ToType(global::System.Type @type, global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToType(@type, provider) : default;
+ }
+
+ ///
+ ushort System.IConvertible.ToUInt16(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToUInt16(provider) : default;
+ }
+
+ ///
+ uint System.IConvertible.ToUInt32(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToUInt32(provider) : default;
+ }
+
+ ///
+ ulong System.IConvertible.ToUInt64(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToUInt64(provider) : default;
+ }
+
+#nullable restore
+ public readonly override global::System.Int32 GetHashCode()
+ {
+ return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value);
+ }
+
+ ///
+ public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]";
+ ///
+ public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]";
+ ///
+ public global::System.String ToString([System.Diagnostics.CodeAnalysis.StringSyntaxAttribute("NumericFormat")] string format) => IsInitialized() ? Value.ToString(format) ?? "" : "[UNINITIALIZED]";
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private readonly void EnsureInitialized()
+ {
+ if (!IsInitialized())
+ {
+#if DEBUG
+ ThrowHelper.ThrowWhenNotInitialized(_stackTrace);
+#else
+ ThrowHelper.ThrowWhenNotInitialized();
+#endif
+ }
+ }
+
+#nullable disable
+ internal sealed class AgeDebugView
+ {
+ private readonly Age _t;
+ AgeDebugView(Age t)
+ {
+ _t = t;
+ }
+
+ public global::System.Boolean IsInitialized => _t.IsInitialized();
+ public global::System.String UnderlyingType => "System.Int32";
+ public global::System.String Value => _t.IsInitialized() ? _t._value.ToString() : "[not initialized]";
+#if DEBUG
+ public global::System.String CreatedWith => _t._stackTrace.ToString() ?? "the From method";
+#endif
+ public global::System.String Conversions => @"Bson";
+ }
+
+#nullable restore
+ static class ThrowHelper
+ {
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenCreatedWithNull() => throw CreateCannotBeNullException();
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized() => throw CreateValidationException("Use of uninitialized Value Object.");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw CreateValidationException("Use of uninitialized Value Object at: " + stackTrace ?? "");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenValidationFails(global::Vogen.Validation validation)
+ {
+ throw CreateValidationException(validation);
+ }
+
+ internal static global::System.Exception CreateValidationException(string message) => new global::Vogen.ValueObjectValidationException(message);
+ internal static global::System.Exception CreateCannotBeNullException() => new global::Vogen.ValueObjectValidationException("Cannot create a value object with null.");
+ internal static global::System.Exception CreateValidationException(global::Vogen.Validation validation)
+ {
+ var ex = CreateValidationException(validation.ErrorMessage);
+ if (validation.Data != null)
+ {
+ foreach (var kvp in validation.Data)
+ {
+ ex.Data[kvp.Key] = kvp.Value;
+ }
+ }
+
+ return ex;
+ }
+ }
+ }
+}
+
+// ------------------------------------------------------------------------------
+//
+// This code was generated by a source generator named Vogen (https://github.com/SteveDunn/Vogen)
+//
+// Changes to this file may cause incorrect behavior and will be lost if
+// the code is regenerated.
+//
+// ------------------------------------------------------------------------------
+// Suppress warnings about [Obsolete] member usage in generated code.
+#pragma warning disable CS0618
+// Suppress warnings for 'Override methods on comparable types'.
+#pragma warning disable CA1036
+// Suppress Error MA0097 : A class that implements IComparable or IComparable should override comparison operators
+#pragma warning disable MA0097
+// Suppress warning for 'The annotation for nullable reference types should only be used in code within a '#nullable' annotations context. Auto-generated code requires an explicit '#nullable' directive in source.'
+// The generator copies signatures from the BCL, e.g. for `TryParse`, and some of those have nullable annotations.
+#pragma warning disable CS8669, CS8632
+#pragma warning disable CS8604 // Possible null reference argument.
+
+// Suppress warnings about CS1591: Missing XML comment for publicly visible type or member 'Type_or_Member'
+#pragma warning disable CS1591
+// Suppress warnings about CS8767 : Nullability of reference types in type of parameter doesn't match implicitly implemented member (possibly because of nullability attributes).
+#pragma warning disable CS8767
+namespace Whatever
+{
+ [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage]
+ [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Vogen", "1.0.0.0")]
+ [global::System.Diagnostics.DebuggerTypeProxyAttribute(typeof(NameDebugView))]
+ [global::System.Diagnostics.DebuggerDisplayAttribute("Underlying type: global::System.String, Value = { _value }")]
+ // ReSharper disable once UnusedType.Global
+ public partial struct Name : global::System.IEquatable, global::System.IEquatable, global::System.IComparable, global::System.IComparable, global::System.IParsable, global::System.IConvertible
+ {
+#if DEBUG
+private readonly global::System.Diagnostics.StackTrace _stackTrace = null!;
+#endif
+#if !VOGEN_NO_VALIDATION
+ private readonly global::System.Boolean _isInitialized;
+#endif
+ private readonly global::System.String _value;
+ ///
+ /// Gets the underlying value if set, otherwise a is thrown.
+ ///
+ public readonly global::System.String Value
+ {
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ EnsureInitialized();
+ return _value;
+ }
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ [global::System.ComponentModel.EditorBrowsable(global::System.ComponentModel.EditorBrowsableState.Never)]
+ public Name()
+ {
+#if DEBUG
+ _stackTrace = new global::System.Diagnostics.StackTrace();
+#endif
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = false;
+#endif
+ _value = default;
+ }
+
+ [global::System.Diagnostics.DebuggerStepThroughAttribute]
+ private Name(global::System.String value)
+ {
+ _value = value;
+#if !VOGEN_NO_VALIDATION
+ _isInitialized = true;
+#endif
+#if DEBUG
+ _stackTrace = null;
+#endif
+ }
+
+ ///
+ /// Builds an instance from the provided underlying type.
+ ///
+ /// The underlying type.
+ /// An instance of this type.
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ public static Name From(global::System.String value)
+ {
+ if (value is null)
+ {
+ ThrowHelper.ThrowWhenCreatedWithNull();
+ return default !;
+ }
+
+ return new Name(value);
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying type.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, false will be returned.
+ ///
+ /// The underlying type.
+ /// An instance of the value object.
+ /// True if the value object can be built, otherwise false.
+ public static bool TryFrom(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ global::System.String value,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out Name vo)
+ {
+ if (value is null)
+ {
+ vo = default;
+ return false;
+ }
+
+ vo = new Name(value);
+ return true;
+ }
+
+ ///
+ /// Tries to build an instance from the provided underlying value.
+ /// If a normalization method is provided, it will be called.
+ /// If validation is provided, and it fails, an error will be returned.
+ ///
+ /// The primitive value.
+ /// A containing either the value object, or an error.
+ public static global::Vogen.ValueObjectOrError TryFrom(global::System.String value)
+ {
+ if (value is null)
+ {
+ return new global::Vogen.ValueObjectOrError(global::Vogen.Validation.Invalid("The value provided was null"));
+ }
+
+ return new global::Vogen.ValueObjectOrError(new Name(value));
+ }
+
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+#if VOGEN_NO_VALIDATION
+#pragma warning disable CS8775
+ public readonly bool IsInitialized() => true;
+#pragma warning restore CS8775
+#else
+ public readonly bool IsInitialized() => _isInitialized;
+#endif
+ public static explicit operator Name(global::System.String value) => From(value);
+ public static explicit operator global::System.String(Name value) => value.Value;
+ // only called internally when something has been deserialized into
+ // its primitive type.
+ private static Name __Deserialize(global::System.String value)
+ {
+ if (value is null)
+ {
+ ThrowHelper.ThrowWhenCreatedWithNull();
+ return default !;
+ }
+
+ return new Name(value);
+ }
+
+ public readonly global::System.Boolean Equals(Name other)
+ {
+ // It's possible to create uninitialized instances via converters such as EfCore (HasDefaultValue), which call Equals.
+ // We treat anything uninitialized as not equal to anything, even other uninitialized instances of this type.
+ if (!IsInitialized() || !other.IsInitialized())
+ return false;
+ return global::System.Collections.Generic.EqualityComparer.Default.Equals(Value, other.Value);
+ }
+
+ public global::System.Boolean Equals(Name other, global::System.Collections.Generic.IEqualityComparer comparer)
+ {
+ return comparer.Equals(this, other);
+ }
+
+ public readonly global::System.Boolean Equals(global::System.String primitive)
+ {
+ return Value.Equals(primitive);
+ }
+
+ public readonly global::System.Boolean Equals(global::System.String primitive, global::System.StringComparer comparer)
+ {
+ return comparer.Equals(Value, primitive);
+ }
+
+ public readonly override global::System.Boolean Equals(global::System.Object obj)
+ {
+ return obj is Name && Equals((Name)obj);
+ }
+
+ public static global::System.Boolean operator ==(Name left, Name right) => left.Equals(right);
+ public static global::System.Boolean operator !=(Name left, Name right) => !(left == right);
+ public static global::System.Boolean operator ==(Name left, global::System.String right) => left.Value.Equals(right);
+ public static global::System.Boolean operator ==(global::System.String left, Name right) => right.Value.Equals(left);
+ public static global::System.Boolean operator !=(global::System.String left, Name right) => !(left == right);
+ public static global::System.Boolean operator !=(Name left, global::System.String right) => !(left == right);
+ public int CompareTo(Name other) => Value.CompareTo(other.Value);
+ public int CompareTo(object other)
+ {
+ if (other is null)
+ return 1;
+ if (other is Name x)
+ return CompareTo(x);
+ ThrowHelper.ThrowArgumentException("Cannot compare to object as it is not of type Name", nameof(other));
+ return 0;
+ }
+
+ ///
+ ///
+ ///
+ /// True if the value passes any validation (after running any optional normalization).
+ ///
+ public static global::System.Boolean TryParse(
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)]
+#endif
+ global::System.String s, global::System.IFormatProvider provider,
+#if NETCOREAPP3_0_OR_GREATER
+[global::System.Diagnostics.CodeAnalysis.MaybeNullWhen(false)]
+#endif
+ out Name result)
+ {
+ if (s is null)
+ {
+ result = default;
+ return false;
+ }
+
+ result = new Name(s);
+ return true;
+ }
+
+ ///
+ ///
+ ///
+ /// The value created via the method.
+ ///
+ /// Thrown when the value can be parsed, but is not valid.
+ public static Name Parse(global::System.String s, global::System.IFormatProvider provider)
+ {
+ return From(s);
+ }
+
+#nullable disable
+#nullable restore
+#nullable disable
+ ///
+ public System.TypeCode GetTypeCode()
+ {
+ return IsInitialized() ? Value.GetTypeCode() : default;
+ }
+
+ ///
+ bool System.IConvertible.ToBoolean(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToBoolean(provider) : default;
+ }
+
+ ///
+ byte System.IConvertible.ToByte(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToByte(provider) : default;
+ }
+
+ ///
+ char System.IConvertible.ToChar(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToChar(provider) : default;
+ }
+
+ ///
+ System.DateTime System.IConvertible.ToDateTime(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToDateTime(provider) : default;
+ }
+
+ ///
+ decimal System.IConvertible.ToDecimal(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToDecimal(provider) : default;
+ }
+
+ ///
+ double System.IConvertible.ToDouble(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToDouble(provider) : default;
+ }
+
+ ///
+ short System.IConvertible.ToInt16(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToInt16(provider) : default;
+ }
+
+ ///
+ int System.IConvertible.ToInt32(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToInt32(provider) : default;
+ }
+
+ ///
+ long System.IConvertible.ToInt64(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToInt64(provider) : default;
+ }
+
+ ///
+ sbyte System.IConvertible.ToSByte(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToSByte(provider) : default;
+ }
+
+ ///
+ float System.IConvertible.ToSingle(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToSingle(provider) : default;
+ }
+
+ ///
+ object System.IConvertible.ToType(global::System.Type @type, global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToType(@type, provider) : default;
+ }
+
+ ///
+ ushort System.IConvertible.ToUInt16(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToUInt16(provider) : default;
+ }
+
+ ///
+ uint System.IConvertible.ToUInt32(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToUInt32(provider) : default;
+ }
+
+ ///
+ ulong System.IConvertible.ToUInt64(global::System.IFormatProvider provider)
+ {
+ return IsInitialized() ? (Value as System.IConvertible).ToUInt64(provider) : default;
+ }
+
+#nullable restore
+ public readonly override global::System.Int32 GetHashCode()
+ {
+ return global::System.Collections.Generic.EqualityComparer.Default.GetHashCode(Value);
+ }
+
+ ///
+ public override global::System.String ToString() => IsInitialized() ? Value.ToString() ?? "" : "[UNINITIALIZED]";
+ ///
+ public global::System.String ToString(global::System.IFormatProvider provider) => IsInitialized() ? Value.ToString(provider) ?? "" : "[UNINITIALIZED]";
+ [global::System.Runtime.CompilerServices.MethodImpl(global::System.Runtime.CompilerServices.MethodImplOptions.AggressiveInlining)]
+ private readonly void EnsureInitialized()
+ {
+ if (!IsInitialized())
+ {
+#if DEBUG
+ ThrowHelper.ThrowWhenNotInitialized(_stackTrace);
+#else
+ ThrowHelper.ThrowWhenNotInitialized();
+#endif
+ }
+ }
+
+#nullable disable
+ internal sealed class NameDebugView
+ {
+ private readonly Name _t;
+ NameDebugView(Name t)
+ {
+ _t = t;
+ }
+
+ public global::System.Boolean IsInitialized => _t.IsInitialized();
+ public global::System.String UnderlyingType => "System.String";
+ public global::System.String Value => _t.IsInitialized() ? _t._value.ToString() : "[not initialized]";
+#if DEBUG
+ public global::System.String CreatedWith => _t._stackTrace.ToString() ?? "the From method";
+#endif
+ public global::System.String Conversions => @"Bson";
+ }
+
+#nullable restore
+ static class ThrowHelper
+ {
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowInvalidOperationException(string message) => throw new global::System.InvalidOperationException(message);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowArgumentException(string message, string arg) => throw new global::System.ArgumentException(message, arg);
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenCreatedWithNull() => throw CreateCannotBeNullException();
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized() => throw CreateValidationException("Use of uninitialized Value Object.");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenNotInitialized(global::System.Diagnostics.StackTrace stackTrace) => throw CreateValidationException("Use of uninitialized Value Object at: " + stackTrace ?? "");
+#if NETCOREAPP3_0_OR_GREATER
+ [global::System.Diagnostics.CodeAnalysis.DoesNotReturnAttribute]
+#endif
+ internal static void ThrowWhenValidationFails(global::Vogen.Validation validation)
+ {
+ throw CreateValidationException(validation);
+ }
+
+ internal static global::System.Exception CreateValidationException(string message) => new global::Vogen.ValueObjectValidationException(message);
+ internal static global::System.Exception CreateCannotBeNullException() => new global::Vogen.ValueObjectValidationException("Cannot create a value object with null.");
+ internal static global::System.Exception CreateValidationException(global::Vogen.Validation validation)
+ {
+ var ex = CreateValidationException(validation.ErrorMessage);
+ if (validation.Data != null)
+ {
+ foreach (var kvp in validation.Data)
+ {
+ ex.Data[kvp.Key] = kvp.Value;
+ }
+ }
+
+ return ex;
+ }
+ }
+ }
+}
+]
\ No newline at end of file