### Install AltaSoft.DomainPrimitives.OpenApiExtensions Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Install the OpenApiExtensions package to your project using the provided NuGet package reference. ```xml ``` -------------------------------- ### Example Domain Primitive Types Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Demonstrates how to define various domain primitive types based on supported underlying types like string, int, decimal, double, float, DateOnly, TimeOnly, DateTime, Guid, and long. These definitions include basic validation placeholders. ```csharp public readonly partial struct EmailAddress : IDomainValue { /* validation */ } public readonly partial struct ProductCode : IDomainValue { /* validation */ } public readonly partial struct Age : IDomainValue { /* validation */ } public readonly partial struct Price : IDomainValue { /* validation */ } public readonly partial struct Weight : IDomainValue { /* validation */ } public readonly partial struct Score : IDomainValue { /* validation */ } public readonly partial struct BirthDate : IDomainValue { /* validation */ } public readonly partial struct BusinessHours : IDomainValue { /* validation */ } public readonly partial struct CreatedAt : IDomainValue { /* validation */ } public readonly partial struct CustomerId : IDomainValue { /* validation */ } public readonly partial struct OrderNumber : IDomainValue { /* validation */ } ``` -------------------------------- ### Add OpenAPI Integration Package Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Install this NuGet package to enable Domain Primitives integration with OpenAPI for API documentation. ```xml ``` -------------------------------- ### Example AsciiString Domain Primitive Source: https://github.com/altasoft/domainprimitives/blob/main/EntityFrameworkCoreExample.md This is an example of an AsciiString domain primitive. It defines validation logic to ensure the string contains only ASCII characters. This primitive will have a ValueConverter generated for it. ```csharp /// /// A domain primitive type representing an ASCII string. /// /// /// The AsciiString ensures that its value contains only ASCII characters. /// public partial class AsciiString : IDomainValue { /// public static PrimitiveValidationResult Validate(string value) { var input = value.AsSpan(); // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < input.Length; i++) { if (!char.IsAscii(input[i])) return "value contains non-ascii characters"; } return PrimitiveValidationResult.Ok; } } ``` -------------------------------- ### Add Swagger/Swashbuckle Integration Package Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Install this NuGet package to enable Domain Primitives integration with Swagger/Swashbuckle for API documentation. ```xml ``` -------------------------------- ### DateOnly Domain Primitive Example Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines a custom DateOnly domain primitive. Shows implicit conversions to and from DateTime. ```csharp public readonly partial struct MyDate : IDomainValue { public static PrimitiveValidationResult Validate(DateOnly value) => PrimitiveValidationResult.Ok; } // Usage examples: var myDate = new MyDate(DateOnly.FromDateTime(DateTime.Now)); // Additional conversions available: DateTime dateTime = myDate; // Implicit conversion to DateTime MyDate fromDateTime = DateTime.Now; // Implicit conversion from DateTime ``` -------------------------------- ### Configure DbContext with Domain Primitive Conversions Source: https://github.com/altasoft/domainprimitives/blob/main/EntityFrameworkCoreExample.md This example shows how to override the ConfigureConventions method in a DbContext class to add custom property conversions for domain primitives by calling the AddDomainPrimitivePropertyConversions extension method. ```csharp public class MyDbContext : DbContext { public MyDbContext(DbContextOptions options) : base(options) { } protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder) { configurationBuilder.AddDomainPrimitivePropertyConversions(); } } ``` -------------------------------- ### TimeOnly Domain Primitive Example Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines a custom TimeOnly domain primitive. Shows implicit conversions to and from DateTime. ```csharp public readonly partial struct MyTime : IDomainValue { public static PrimitiveValidationResult Validate(TimeOnly value) => PrimitiveValidationResult.Ok; } // Usage examples: var myTime = new MyTime(TimeOnly.FromDateTime(DateTime.Now)); // Additional conversions available: DateTime dateTime = myTime; // Implicit conversion to DateTime MyTime fromDateTime = DateTime.Now; // Implicit conversion from DateTime ``` -------------------------------- ### Add XML Data Types Support Package Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Install this NuGet package to add support for XML data types within Domain Primitives. ```xml ``` -------------------------------- ### Generated EntityFrameworkCore Value Converter for AsciiString Source: https://github.com/altasoft/domainprimitives/blob/main/EntityFrameworkCoreExample.md This is an example of a generated EntityFrameworkCore ValueConverter for the AsciiString domain primitive. It handles the conversion between the AsciiString type and its underlying string representation for Entity Framework Core. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using AltaSoft.DomainPrimitives.XmlDataTypes; using System; using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore.Storage.ValueConversion; using AltaSoft.DomainPrimitives; namespace AltaSoft.DomainPrimitives.XmlDataTypes.EntityFrameworkCore.Converters; /// /// ValueConverter for /// public sealed class AsciiStringValueConverter : ValueConverter { /// /// Constructor to create AsciiStringValueConverter /// public AsciiStringValueConverter() : base(v => v, v => v) { } } ``` -------------------------------- ### Create a Custom Positive Integer Domain Type Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Define a custom domain type 'PositiveInteger' that inherits from IDomainValue. This example uses a readonly struct for optimal performance and includes a validation method to ensure the integer value is positive. ```csharp public readonly partial struct PositiveInteger : IDomainValue { /// public static PrimitiveValidationResult Validate(int value) { if (value <= 0) return PrimitiveValidationResult.Error("value is non-positive"); return PrimitiveValidationResult.Ok; } } ``` -------------------------------- ### Specify Serialization Format for Date-Related Types Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Use the `SerializationFormatAttribute` to define custom serialization and deserialization formats for date-related domain primitives. This example shows a `GDay` type with a specific format for `DateOnly`. ```csharp /// /// Represents an XML GDay value object, providing operations for parsing and handling gDay values. /// [SerializationFormat("dd")] public readonly partial struct GDay : IDomainValue { /// public static PrimitiveValidationResult Validate(int value) { return PrimitiveValidationResult.Ok; } /// public static DateOnly Default => default; // Customized string representation of DateOnly /// public static string ToString(DateOnly value) => value.ToString("dd"); } ``` -------------------------------- ### Project File References for Domain Primitives Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Shows how to add the necessary AltaSoft.DomainPrimitives NuGet packages to your project file. Ensure you are using .NET 8 or higher. ```xml ``` -------------------------------- ### Configure OpenAPI Services and Domain Primitive Transformers Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Configure OpenAPI services and register domain primitive OpenAPI schema transformers in your application's startup. This ensures domain primitives are correctly represented in OpenAPI documentation. ```csharp var builder = WebApplication.CreateBuilder(args); // Add OpenAPI services builder.Services.AddOpenApi(); // Register domain primitive OpenAPI schema transformers builder.Services.AddDomainPrimitiveOpenApiSchemaTransformers(); var app = builder.Build(); app.MapOpenApi(); app.Run(); ``` -------------------------------- ### Enable EntityFrameworkCore Value Converter Generation Source: https://github.com/altasoft/domainprimitives/blob/main/EntityFrameworkCoreExample.md Add this property to your .csproj file to enable the generation of EntityFrameworkCore Value Converters. Ensure EntityFrameworkCore is referenced in your project. ```xml true ``` -------------------------------- ### JSON Serialization and Deserialization with Domain Primitives Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Shows how DomainPrimitive types can be serialized to and deserialized from JSON. Ensure the domain primitive implements IDomainValue and has a Validate method. The SupportedOperations attribute can be used to prevent mathematical operators. ```csharp [SupportedOperations] // no mathematical operators should be generated public readonly partial struct CustomerId : IDomainValue { public static PrimitiveValidationResult Validate(int value) { if (value <= 0) return "Must be a positive number"; return PrimitiveValidationResult.Ok; } } public sealed class Transaction { public CustomerId FromId { get; set; } public CustomerId? ToId { get; set; } public PositiveAmount Amount { get; set; } public PositiveAmount? Fees { get; set; } } public static void JsonSerializationAndDeserialization() { var amount = new Transaction() { Amount = 100.523m, Fees = null, FromId = 1, ToId = null }; var jsonValue = JsonSerializer.Serialize(amount); //this will produce the same result as changing customerId to int and PositiveAmount to decimal var newValue = JsonSerializer.Deserialize(jsonValue) } ``` ```json { "FromId": 1, "ToId": null, "Amount": 100.523, "Fees": null } ``` -------------------------------- ### Transform Method for Input Normalization Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Demonstrates the use of the static Transform method within a Domain Primitive to preprocess input values before validation or construction. The Transform method must match the value type and can be private, internal, or public. ```csharp public sealed partial class ToUpperString : IDomainValue { static PrimitiveValidationResult Validate(string value) => value.All(char.IsUpper) ? PrimitiveValidationResult.Ok : "Value must be all uppercase."; // This method is automatically invoked before validation and construction. static string Transform(string value) => value.ToUpperInvariant(); } ``` -------------------------------- ### OpenApiHelper for Domain Primitive Schemas Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Provides a frozen dictionary for mapping DomainPrimitive types to OpenApiSchema definitions, enabling efficient lookups for custom OpenAPI integration scenarios. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using AltaSoft.DomainPrimitives; using System; using System.Collections.Frozen; using System.Collections.Generic; using Microsoft.OpenApi; namespace AltaSoft.DomainPrimitives.Converters.Helpers; /// /// Helper class providing methods to configure OpenApiSchema mappings for DomainPrimitive types /// public static class OpenApiHelper { /// /// Mapping of DomainPrimitive types to OpenApiSchema definitions. /// public static FrozenDictionary Schemas = new Dictionary() { { typeof(PositiveInteger), new OpenApiSchema { Type = JsonSchemaType.Integer, Format = "int32", Title = "PositiveInteger" } } }.ToFrozenDictionary(); } ``` -------------------------------- ### IXmlSerializable GetSchema Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IXmlSerializable interface by returning null for GetSchema, indicating no schema is provided. ```csharp /// public XmlSchema? GetSchema() => null; ``` -------------------------------- ### IConvertible ToSingle Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a Single (float). ```csharp /// float IConvertible.ToSingle(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToSingle(provider); ``` -------------------------------- ### PositiveInteger Comparison Methods Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements comparison logic for PositiveInteger, allowing it to be compared with other PositiveIntegers and objects. Handles uninitialized states. ```csharp /// public int CompareTo(object? obj) { if (obj is null) return 1; if (obj is PositiveInteger c) return CompareTo(c); throw new ArgumentException("Object is not a PositiveInteger", nameof(obj)); } /// public int CompareTo(PositiveInteger other) { if (!other._isInitialized) return 1; if (!_isInitialized) return -1; return _value.CompareTo(other._value); } ``` -------------------------------- ### Chaining Domain Primitives: BetweenOneAnd100 Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines a BetweenOneAnd100 domain primitive that inherits from PositiveInteger and adds an upper bound check. It demonstrates implicit conversion from string to PrimitiveValidationResult. ```csharp public readonly partial struct BetweenOneAnd100 : IDomainValue { public static PrimitiveValidationResult Validate(PositiveInteger value) { if (value < 100) return "Value must be less than 100"; //implicit operator to convert string to PrimitiveValidationResult return PrimitiveValidationResult.Ok; } } ``` -------------------------------- ### Implicit Usage of DomainType Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Demonstrates implicit conversion to and from a DomainPrimitive type. Ensure the IDomainValue interface is implemented and validation logic is provided. ```csharp public readonly partial struct PositiveAmount : IDomainValue { public static PrimitiveValidationResult Validate(decimal value) { if (value <= 0m) return "Must be a a positive number"; return PrimitiveValidationResult.Ok; } } public static class Example { public static void ImplicitConversion() { var amount = new PositiveAmount(100m); PositiveAmount amount2 = 100m; // implicitly converted to PositiveAmount //implicilty casted to decimal decimal amountInDecimal = amount + amount2; } } ``` -------------------------------- ### IUtf8SpanFormattable Implementation for NET8_0+ Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IUtf8SpanFormattable interface for efficient UTF-8 span formatting. Requires .NET 8.0 or greater. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool TryFormat(Span utf8Destination, out int bytesWritten, ReadOnlySpan format, IFormatProvider? provider) { return ((IUtf8SpanFormattable)_valueOrThrow).TryFormat(utf8Destination, out bytesWritten, format, provider); } ``` -------------------------------- ### IConvertible ToSByte Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to an SByte. ```csharp /// sbyte IConvertible.ToSByte(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToSByte(provider); ``` -------------------------------- ### Use Reflection-Based OpenAPI Schema Transformer Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Configure OpenAPI services to use the reflection-based transformer for domain primitives. This is useful when you prefer runtime reflection over generated OpenAPI helper mappings. ```csharp var builder = WebApplication.CreateBuilder(args); // Add OpenAPI services builder.Services.AddOpenApi(options => { // Use reflection-based transformer instead of generated mappings options.AddSchemaTransformer(new UnderlyingPrimitiveOpenApiSchemaTransformer()); }); var app = builder.Build(); app.MapOpenApi(); app.Run(); ``` -------------------------------- ### IConvertible ToUInt64 Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a UInt64. ```csharp /// ulong IConvertible.ToUInt64(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToUInt64(provider); ``` -------------------------------- ### Integer Parsing and Validation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Handles parsing a string to an integer and then attempting to create a PositiveInteger. Returns true if successful, false otherwise. ```csharp if (!int.TryParse(s, provider, out var value)) { result = default; return false; } if (TryCreate(value, out var created)) { result = created.Value; return true; } result = default; return false; ``` -------------------------------- ### IConvertible ToInt64 Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to an Int64. ```csharp /// long IConvertible.ToInt64(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToInt64(provider); ``` -------------------------------- ### Add Swagger Mappings for Domain Primitives Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Adds Swagger mappings for custom types like PositiveInteger to ensure proper OpenAPI documentation generation. This requires the Swashbuckle.AspNetCore.SwaggerGen NuGet package. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using AltaSoft.DomainPrimitives; using Microsoft.Extensions.DependencyInjection; using Swashbuckle.AspNetCore.SwaggerGen; using Microsoft.OpenApi.Models; namespace AltaSoft.DomainPrimitives.Converters.Extensions; /// /// Helper class providing methods to configure Swagger mappings for DomainPrimitive types of AltaSoft.DomainPrimitives /// public static class SwaggerTypeHelper { /// /// Adds Swagger mappings for specific custom types to ensure proper OpenAPI documentation generation. /// /// The SwaggerGenOptions instance to which mappings are added. /// /// The method adds Swagger mappings for the following types: /// /// public static void AddSwaggerMappings(this SwaggerGenOptions options) { options.MapType(() => new OpenApiSchema { Type = "integer", Format = "int32", Title = "PositiveInteger", Description = @"A domain primitive type representing a positive integer." }); options.MapType(() => new OpenApiSchema { Type = "integer", Format = "int32", Nullable = true, Title = "Nullable", Description = @"A domain primitive type representing a positive integer." }); } ``` -------------------------------- ### IConvertible ToByte Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a byte. ```csharp /// byte IConvertible.ToByte(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToByte(provider); ``` -------------------------------- ### Chaining Domain Primitives: PositiveInteger Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines a PositiveInteger domain primitive that validates against non-positive values. This serves as a base for chained primitives. ```csharp public readonly partial struct PositiveInteger : IDomainValue { /// public static PrimitiveValidationResult Validate(int value) { if (value <= 0) return PrimitiveValidationResult.Error("value is non-positive"); return PrimitiveValidationResult.Ok; } } ``` -------------------------------- ### IConvertible ToUInt32 Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a UInt32. ```csharp /// uint IConvertible.ToUInt32(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToUInt32(provider); ``` -------------------------------- ### IXmlSerializable WriteXml Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IXmlSerializable interface to write the underlying integer value to XML using its ToXmlString() representation. ```csharp /// public void WriteXml(XmlWriter writer) => writer.WriteValue(((int)_valueOrThrow).ToXmlString()); ``` -------------------------------- ### IConvertible ToString Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a string. ```csharp /// string IConvertible.ToString(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToString(provider); ``` -------------------------------- ### PositiveInteger TryParse Method Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements a TryParse method for safely converting a string to a PositiveInteger without throwing exceptions on failure. Returns a boolean indicating success. ```csharp /// public static bool TryParse([NotNullWhen(true)] string? s, IFormatProvider? provider, [MaybeNullWhen(false)] out PositiveInteger result) { ``` -------------------------------- ### IConvertible ToDecimal Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a decimal. ```csharp /// decimal IConvertible.ToDecimal(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToDecimal(provider); ``` -------------------------------- ### IConvertible ToDateTime Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a DateTime. ```csharp /// DateTime IConvertible.ToDateTime(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToDateTime(provider); ``` -------------------------------- ### IConvertible ToUInt16 Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a UInt16. ```csharp /// ushort IConvertible.ToUInt16(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToUInt16(provider); ``` -------------------------------- ### PositiveInteger Equality Operators Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines equality comparison operators (== and !=) for PositiveInteger instances. Ensures proper handling of initialized states. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override bool Equals(object? obj) => obj is PositiveInteger other && Equals(other); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public bool Equals(PositiveInteger other) { if (!_isInitialized || !other._isInitialized) return false; return _value.Equals(other._value); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator ==(PositiveInteger left, PositiveInteger right) => left.Equals(right); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator !=(PositiveInteger left, PositiveInteger right) => !(left == right); ``` -------------------------------- ### IConvertible ToDouble Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a double. ```csharp /// double IConvertible.ToDouble(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToDouble(provider); ``` -------------------------------- ### Implicit Conversion from PositiveInteger Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Provides implicit conversion from PositiveInteger and nullable PositiveInteger to int and nullable int. This allows direct use of PositiveInteger where an int is expected. ```csharp /// /// Implicit conversion from to /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator int(PositiveInteger value) => (int)value._valueOrThrow; /// /// Implicit conversion from (nullable) to (nullable) /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NotNullIfNotNull(nameof(value))] public static implicit operator int?(PositiveInteger? value) => value is null ? null : (int?)value.Value._valueOrThrow; ``` -------------------------------- ### PositiveInteger Arithmetic Operators Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines standard arithmetic operators (+, -, *, /, %) for PositiveInteger. These operations return a new PositiveInteger instance. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static PositiveInteger operator +(PositiveInteger left, PositiveInteger right) => new(left._valueOrThrow + right._valueOrThrow); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static PositiveInteger operator -(PositiveInteger left, PositiveInteger right) => new(left._valueOrThrow - right._valueOrThrow); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static PositiveInteger operator *(PositiveInteger left, PositiveInteger right) => new(left._valueOrThrow * right._valueOrThrow); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static PositiveInteger operator /(PositiveInteger left, PositiveInteger right) => new(left._valueOrThrow / right._valueOrThrow); /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static PositiveInteger operator %(PositiveInteger left, PositiveInteger right) => new(left._valueOrThrow % right._valueOrThrow); ``` -------------------------------- ### IConvertible ToInt32 Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to an Int32. ```csharp /// int IConvertible.ToInt32(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToInt32(provider); ``` -------------------------------- ### PositiveInteger Parse Method Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Provides a static Parse method for converting a string representation to a PositiveInteger. Uses the standard int.Parse for underlying conversion. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static PositiveInteger Parse(string s, IFormatProvider? provider) => int.Parse(s, provider); ``` -------------------------------- ### Implicit Conversion to PositiveInteger Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Provides implicit conversion from int and nullable int to PositiveInteger. This allows direct assignment of integer values. ```csharp /// /// Implicit conversion from to /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static implicit operator PositiveInteger(int value) => new(value); /// /// Implicit conversion from (nullable) to (nullable) /// [MethodImpl(MethodImplOptions.AggressiveInlining)] [return: NotNullIfNotNull(nameof(value))] public static implicit operator PositiveInteger?(int? value) => value is null ? null : new(value.Value); ``` -------------------------------- ### GetHashCode Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Overrides the GetHashCode method to provide a hash code based on the underlying integer value. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override int GetHashCode() => _valueOrThrow.GetHashCode(); ``` -------------------------------- ### IConvertible ToInt16 Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to an Int16. ```csharp /// short IConvertible.ToInt16(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToInt16(provider); ``` -------------------------------- ### Add Domain Primitive Property Conversions Extension Method Source: https://github.com/altasoft/domainprimitives/blob/main/EntityFrameworkCoreExample.md This extension method adds Entity Framework Core Value Converters for various domain primitive types to the ModelConfigurationBuilder. It's used to ensure proper mapping to the EFCore ORM. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using AltaSoft.DomainPrimitives.XmlDataTypes; using Microsoft.EntityFrameworkCore; using AltaSoft.DomainPrimitives.XmlDataTypes.EntityFrameworkCore.Converters; namespace AltaSoft.DomainPrimitives.XmlDataTypes.Converters.Extensions; /// /// Helper class providing methods to configure EntityFrameworkCore ValueConverters for DomainPrimitive types of AltaSoft.DomainPrimitives.XmlDataTypes /// public static class ModelConfigurationBuilderExt { /// /// Adds EntityFrameworkCore ValueConverters for specific custom types to ensure proper mapping to EFCore ORM. /// /// The ModelConfigurationBuilder instance to which converters are added. public static ModelConfigurationBuilder AddDomainPrimitivePropertyConversions(this ModelConfigurationBuilder configurationBuilder) { configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); configurationBuilder.Properties().HaveConversion(); return configurationBuilder; } } ``` -------------------------------- ### IConvertible ToChar Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a char. ```csharp /// char IConvertible.ToChar(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToChar(provider); ``` -------------------------------- ### Customize Numeric Operators with SupportedOperationsAttribute Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Use the `SupportedOperationsAttribute` to explicitly define which mathematical operators are generated for numeric domain primitives. If this attribute is applied, manual specification of operators becomes mandatory. ```csharp [SupportedOperations(Addition = false, Division = false, Modulus = false, Multiplication = true, Subtraction = true)] public readonly partial struct PositiveInteger : IDomainValue { /// public static PrimitiveValidationResult Validate(int value) { if (value <= 0) return PrimitiveValidationResult.Error("value is non-positive"); return PrimitiveValidationResult.Ok; } } ``` -------------------------------- ### IXmlSerializable ReadXml Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IXmlSerializable interface to read an integer value from XML, validate it, and assign it to the internal value. ```csharp /// public void ReadXml(XmlReader reader) { var value = reader.ReadElementContentAs(); ValidateOrThrow(value); System.Runtime.CompilerServices.Unsafe.AsRef(in _value) = value; System.Runtime.CompilerServices.Unsafe.AsRef(in _isInitialized) = true; } ``` -------------------------------- ### Implement Specific Interfaces for Operator Customization Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Further customize operators by implementing specific interfaces like `IAdditionOperators`. This approach overrides any operators generated by default or specified via attributes. ```csharp public readonly partial struct PositiveInteger : IDomainValue, IAdditionOperators { /// public static PrimitiveValidationResult Validate(int value) { if (value <= 0) return PrimitiveValidationResult.Error("value is non-positive"); return PrimitiveValidationResult.Ok; } // custom + operator public static PositiveInteger operator +(PositiveInteger left, PositiveInteger right) { return (left._value + right._value + 1); } } ``` -------------------------------- ### PositiveInteger JsonConverter Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Provides JSON conversion for PositiveInteger, handling serialization and deserialization. It leverages internal converters for Int32 and throws JsonException for invalid domain values. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using AltaSoft.DomainPrimitives; using System; using System.Text.Json; using System.Text.Json.Serialization; using System.Globalization; using System.Text.Json.Serialization.Metadata; namespace AltaSoft.DomainPrimitives.Converters; /// /// JsonConverter for /// public sealed class PositiveIntegerJsonConverter : JsonConverter { /// public override PositiveInteger Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { try { return JsonInternalConverters.Int32Converter.Read(ref reader, typeToConvert, options); } catch (InvalidDomainValueException ex) { throw new JsonException(ex.Message); } } /// public override void Write(Utf8JsonWriter writer, PositiveInteger value, JsonSerializerOptions options) { JsonInternalConverters.Int32Converter.Write(writer, (int)value, options); } /// public override PositiveInteger ReadAsPropertyName(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options) { try { return JsonInternalConverters.Int32Converter.ReadAsPropertyName(ref reader, typeToConvert, options); } catch (InvalidDomainValueException ex) { throw new JsonException(ex.Message); } } /// public override void WriteAsPropertyName(Utf8JsonWriter writer, PositiveInteger value, JsonSerializerOptions options) { JsonInternalConverters.Int32Converter.WriteAsPropertyName(writer, (int)value, options); } } ``` -------------------------------- ### StringLengthAttribute for Domain Primitives Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Applies string length restrictions to a domain primitive using StringLengthAttribute. The 'validate' property can control automatic enforcement. ```csharp [StringLength(minimumLength:1, maximumLength:100, validate:false)] public partial class AsciiString : IDomainValue { /// public static PrimitiveValidationResult Validate(string value) { var input = value.AsSpan(); // ReSharper disable once ForCanBeConvertedToForeach for (var i = 0; i < input.Length; i++) { if (!char.IsAscii(input[i])) return "value contains non-ascii characters"; } return PrimitiveValidationResult.Ok; } } ``` -------------------------------- ### Disable Domain Primitive Generation Features Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Configures .csproj file to disable generation of specific converters, Swagger mappers, XML serialization, and operators. ```xml false false false false false false ``` -------------------------------- ### IConvertible ToType Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a specified type. ```csharp /// object IConvertible.ToType(Type conversionType, IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToType(conversionType, provider); ``` -------------------------------- ### PositiveInteger Relational Operators Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines relational operators (<, <=, >, >=) for PositiveInteger, enabling direct comparison between instances. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator <(PositiveInteger left, PositiveInteger right) => left._valueOrThrow < right._valueOrThrow; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator <=(PositiveInteger left, PositiveInteger right) => left._valueOrThrow <= right._valueOrThrow; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator >(PositiveInteger left, PositiveInteger right) => left._valueOrThrow > right._valueOrThrow; /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public static bool operator >=(PositiveInteger left, PositiveInteger right) => left._valueOrThrow >= right._valueOrThrow; ``` -------------------------------- ### IConvertible ToBoolean Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to convert the underlying Int32 value to a boolean. ```csharp /// bool IConvertible.ToBoolean(IFormatProvider? provider) => ((IConvertible)(Int32)_valueOrThrow).ToBoolean(provider); ``` -------------------------------- ### IConvertible TypeCode Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implements the IConvertible interface to return the TypeCode of the underlying Int32 value. ```csharp /// TypeCode IConvertible.GetTypeCode() => ((IConvertible)(Int32)_valueOrThrow).GetTypeCode(); ``` -------------------------------- ### PositiveInteger Class Definition Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Defines the PositiveInteger struct, including its properties, constructors, and interfaces for operations like arithmetic and comparison. It uses a private constructor for internal initialization after validation. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using System; using System.Numerics; using System.Diagnostics; using System.Runtime.CompilerServices; using AltaSoft.DomainPrimitives; using System.Diagnostics.CodeAnalysis; using System.Text.Json.Serialization; using AltaSoft.DomainPrimitives.XmlDataTypes.Converters; using System.ComponentModel; using System.Xml; using System.Xml.Schema; using System.Xml.Serialization; namespace AltaSoft.DomainPrimitives.XmlDataTypes; [JsonConverter(typeof(PositiveIntegerJsonConverter))] [TypeConverter(typeof(PositiveIntegerTypeConverter))] [UnderlyingPrimitiveType(typeof(int))] [DebuggerDisplay("{_value}")] public readonly partial struct PositiveInteger : IEquatable , IComparable , IComparable , IAdditionOperators , ISubtractionOperators , IMultiplyOperators , IDivisionOperators , IModulusOperators , IComparisonOperators , IParsable , IConvertible , IXmlSerializable #if NET8_0_OR_GREATER , IUtf8SpanFormattable #endif { /// public Type GetUnderlyingPrimitiveType() => typeof(int); /// public object GetUnderlyingPrimitiveValue() => (int)this; private int _valueOrThrow => _isInitialized ? _value : throw new InvalidDomainValueException("The domain value has not been initialized", this); [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly int _value; [DebuggerBrowsable(DebuggerBrowsableState.Never)] private readonly bool _isInitialized; /// /// Initializes a new instance of the class by validating the specified value using static method. /// /// The value to be validated. public PositiveInteger(int value) : this(value, true) { } private PositiveInteger(int value, bool validate) { if (validate) { ValidateOrThrow(value); } _value = value; _isInitialized = true; } /// [Obsolete("Domain primitive cannot be created using empty Constructor", true)] public PositiveInteger() { } /// /// Tries to create an instance of AsciiString from the specified value. /// /// The value to create PositiveInteger from /// When this method returns, contains the created PositiveInteger if the conversion succeeded, or null if the conversion failed. /// true if the conversion succeeded; otherwise, false. public static bool TryCreate(int value, [NotNullWhen(true)] out PositiveInteger? result) { return TryCreate(value, out result, out _); } /// /// Tries to create an instance of AsciiString from the specified value. /// /// The value to create PositiveInteger from /// When this method returns, contains the created PositiveInteger if the conversion succeeded, or null if the conversion failed. /// When this method returns, contains the error message if the conversion failed; otherwise, null. /// true if the conversion succeeded; otherwise, false. public static bool TryCreate(int value,[NotNullWhen(true)] out PositiveInteger? result, [NotNullWhen(false)] out string? errorMessage) { var validationResult = Validate(value); if (!validationResult.IsValid) { result = null; errorMessage = validationResult.ErrorMessage; return false; } result = new (value, false); errorMessage = null; return true; } /// /// Validates the specified value and throws an exception if it is not valid. /// /// The value to validate /// Thrown when the value is not valid. public void ValidateOrThrow(int value) { var result = Validate(value); ``` -------------------------------- ### PositiveInteger TypeConverter Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Provides TypeConverter functionality for PositiveInteger, enabling conversion from other types. It extends Int32Converter and handles potential FormatException during conversion. ```csharp //------------------------------------------------------------------------------ // // This code was generated by 'AltaSoft DomainPrimitives Generator'. // Changes to this file may cause incorrect behavior and will be lost if the code is regenerated. // //------------------------------------------------------------------------------ #nullable enable using AltaSoft.DomainPrimitives; using System; using System.ComponentModel; using System.Globalization; namespace AltaSoft.DomainPrimitives.Converters; /// /// TypeConverter for /// public sealed class PositiveIntegerTypeConverter : Int32Converter { /// public override object? ConvertFrom(ITypeDescriptorContext? context, CultureInfo? culture, object value) { var result = base.ConvertFrom(context, culture, value); if (result is null) return null; try { return new PositiveInteger((int)result); } catch (InvalidDomainValueException ex) { throw new FormatException("Cannot parse PositiveInteger", ex); } } } ``` -------------------------------- ### Override Default ToString Method Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Implement a static virtual `ToString` method to override the default `ToString` behavior of `IDomainValue`. This allows for custom string representations of domain primitive values. ```csharp static virtual string ToString(T value) => value.ToString() ?? string.Empty; ``` -------------------------------- ### ToString Override Implementation Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Overrides the ToString method to return the string representation of the underlying integer value. ```csharp /// [MethodImpl(MethodImplOptions.AggressiveInlining)] public override string ToString() => _valueOrThrow.ToString(); ``` -------------------------------- ### Restricting Operations on Chained Domain Primitives Source: https://github.com/altasoft/domainprimitives/blob/main/README.md Applies SupportedOperationsAttribute to a chained domain primitive to explicitly disable certain operations, such as addition. ```csharp [SupportedOperations(Addition=false)] public readonly partial struct BetweenOneAnd100 : IDomainValue { public static PrimitiveValidationResult Validate(PositiveInteger value) { if (value < 100) return "Value must be less than 100"; return PrimitiveValidationResult.Ok; } } ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.