Skip to content

Commit 161df5f

Browse files
authored
Merge pull request #25 from altasoft/copilot/fix-f81c56dd-12b4-43f7-a59e-40454bb80c8f
docs: update README with comprehensive new features and enhanced documentation
2 parents d606dca + 2ca598e commit 161df5f

1 file changed

Lines changed: 84 additions & 15 deletions

File tree

README.md

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
- [Prerequisites](#prerequisites)
1414
- [Installation](#installation)
1515
- [Creating your Domain type](#creating-your-domain-type)
16+
- [Managing Generated Operators for numeric types](#managing-generated-operators-for-numeric-types)
17+
- [Managing Serialization Format for date-related types](#managing-serialization-format-for-date-related-types)
18+
- [Enhanced DateTime Interoperability](#enhanced-datetime-interoperability)
1619
- [Json Conversion](#json-conversion)
1720
- [Transform Method](#transform-method)
1821
- [Contributions](#contributions)
@@ -34,14 +37,20 @@ With `AltaSoft.DomainPrimitives`, experience an accelerated development process
3437

3538
The **AltaSoft.DomainPrimitives.Generator** offers a diverse set of features:
3639

37-
* **Implicit Operators:** Streamlines type conversion to/from the underlying primitive type. [Example](#implicit-usage-of-domaintype)
40+
* **Implicit Operators:** Streamlines type conversion to/from the underlying primitive type, including nullable conversions. [Example](#implicit-usage-of-domaintype)
41+
* **Enhanced Date/Time Conversions:** `DateOnly` and `TimeOnly` domain primitives include additional implicit conversion operators to/from `DateTime` for seamless interoperability.
3842
* **Specialized Constructor Generation:** Automatically validates and constructs instances of this domain type. This constructor, tailored for the domain primitive, utilizes the underlying type as a parameter, ensuring the value's correctness within the domain.
3943
* **TryCreate method:** Introduces a TryCreate method that attempts to create an instance of the domain type and returns a bool indicating the success or failure of the creation process, along with any validation errors.
40-
* **JsonConverters:** Handles JSON serialization and deserialization for the underlying type. [Example](#json-conversion)
44+
* **JsonConverters:** Handles JSON serialization and deserialization for the underlying type, including property name serialization support. [Example](#json-conversion)
4145
* **TypeConverters:** Assists in type conversion to/from it's underlying type. [Please refer to generated type converter below](#type-converter)
42-
* **Swagger Custom Type Mappings:** Facilitates easy integration with Swagger by treating the primitive type as it's underlying type. [Please refer to generated swagger helper below](#swagger-mappers)
43-
* **Interface Implementations:** All DomainPritmitives Implement `IConvertible`, `IComparable`, `IComparable<T>`, `IEquatable<T>`, `IEqualityComparer<T>`, `IParsable` interfaces.
44-
* **NumberType Operations:** Automatically generates basic arithmetic and comparison operators, by implementing Static abstract interfaces. [More details regarding numeric types](#number-types-attribute)
46+
* **Swagger Custom Type Mappings:** Facilitates easy integration with Swagger by treating the primitive type as it's underlying type, with full nullable support. [Please refer to generated swagger helper below](#swagger-mappers)
47+
* **Interface Implementations:** All DomainPrimitives implement comprehensive interfaces for full framework integration:
48+
- `IEquatable<T>`, `IComparable`, `IComparable<T>` for equality and comparison operations
49+
- `IConvertible` for type conversion support
50+
- `IParsable<T>` for parsing from strings
51+
- `ISpanFormattable` and `IUtf8SpanFormattable` (NET8+) for efficient formatting
52+
- Numeric types implement `IAdditionOperators<T>`, `ISubtractionOperators<T>`, etc. as appropriate
53+
* **NumberType Operations:** Automatically generates basic arithmetic and comparison operators, by implementing Static abstract interfaces. [More details regarding numeric types](#managing-generated-operators-for-numeric-types)
4554
* **IParsable Implementation:** Automatically generates parsing for non-string types.
4655
* **XML Serialiaziton** Generates IXmlSerializable interface implementation, to serialize and deserialize from/to xml.
4756
* **EntityFrameworkCore ValueConverters** Facilitates seamless integration with EntityFrameworkCore by using ValueConverters to treat the primitive type as its underlying type. For more details, refer to [EntityFrameworkCore ValueConverters](EntityFrameworkCoreExample.md)
@@ -51,8 +60,8 @@ The **AltaSoft.DomainPrimitives.Generator** offers a diverse set of features:
5160
2. `Guid`
5261
3. `byte`
5362
4. `sbyte`
54-
5. `short`
55-
6. `ushort`
63+
5. `short` (Int16)
64+
6. `ushort` (UInt16)
5665
7. `int`
5766
8. `uint`
5867
9. `long`
@@ -68,6 +77,31 @@ The **AltaSoft.DomainPrimitives.Generator** offers a diverse set of features:
6877
19. `DateOnly`
6978
20. `TimeOnly`
7079

80+
### Example Primitive Types
81+
82+
You can create domain primitive types for any supported underlying type. Here are some examples:
83+
84+
```csharp
85+
// String-based primitives
86+
public readonly partial struct EmailAddress : IDomainValue<string> { /* validation */ }
87+
public readonly partial struct ProductCode : IDomainValue<string> { /* validation */ }
88+
89+
// Numeric primitives
90+
public readonly partial struct Age : IDomainValue<int> { /* validation */ }
91+
public readonly partial struct Price : IDomainValue<decimal> { /* validation */ }
92+
public readonly partial struct Weight : IDomainValue<double> { /* validation */ }
93+
public readonly partial struct Score : IDomainValue<float> { /* validation */ }
94+
95+
// Date/Time primitives
96+
public readonly partial struct BirthDate : IDomainValue<DateOnly> { /* validation */ }
97+
public readonly partial struct BusinessHours : IDomainValue<TimeOnly> { /* validation */ }
98+
public readonly partial struct CreatedAt : IDomainValue<DateTime> { /* validation */ }
99+
100+
// Identifier primitives
101+
public readonly partial struct CustomerId : IDomainValue<Guid> { /* validation */ }
102+
public readonly partial struct OrderNumber : IDomainValue<long> { /* validation */ }
103+
```
104+
71105

72106
## Getting Started
73107

@@ -621,13 +655,16 @@ static virtual string ToString(T value) => value.ToString() ?? string.Empty;
621655

622656
Mathematical operators for particular numeric types can be customized using the `SupportedOperationsAttribute`. If left unspecified, all operators are generated by default (as shown below). Once this attribute is applied, manual specification of the operators becomes mandatory. Note that for `byte`, `sbyte`, `short`, and `ushort` types, mathematical operators will not be generated by default.
623657

658+
**Special Note for `byte`, `sbyte`, `short`, and `ushort` types:** When mathematical operators are enabled for these smaller integer types (via `SupportedOperationsAttribute`), an additional private constructor accepting an `int` parameter is automatically generated to handle overflow scenarios properly during mathematical operations.
659+
624660
### Default numeric types Generated Operators
625661
1. `byte, sbyte` => `None`
626662
2. `short, ushort` => `None`
627663
3. `int, uint` => `+ - / * %`
628-
3. `long, ulong` => `+ - / * %`
629-
3. `double` => `+ - / * %`
630-
3. `decimal` => `+ - / * %`
664+
4. `long, ulong` => `+ - / * %`
665+
5. `float` => `+ - / * %`
666+
6. `double` => `+ - / * %`
667+
7. `decimal` => `+ - / * %`
631668

632669
### using `SupportedOperationsAttribute`
633670

@@ -696,6 +733,40 @@ public readonly partial struct GDay : IDomainValue<DateOnly>
696733
}
697734
```
698735

736+
## Enhanced DateTime Interoperability
737+
738+
Domain primitives based on `DateOnly` and `TimeOnly` include additional implicit conversion operators for seamless interoperability with `DateTime`:
739+
740+
### DateOnly Domain Primitives
741+
```csharp
742+
public readonly partial struct MyDate : IDomainValue<DateOnly>
743+
{
744+
public static PrimitiveValidationResult Validate(DateOnly value) => PrimitiveValidationResult.Ok;
745+
}
746+
747+
// Usage examples:
748+
var myDate = new MyDate(DateOnly.FromDateTime(DateTime.Now));
749+
750+
// Additional conversions available:
751+
DateTime dateTime = myDate; // Implicit conversion to DateTime
752+
MyDate fromDateTime = DateTime.Now; // Implicit conversion from DateTime
753+
```
754+
755+
### TimeOnly Domain Primitives
756+
```csharp
757+
public readonly partial struct MyTime : IDomainValue<TimeOnly>
758+
{
759+
public static PrimitiveValidationResult Validate(TimeOnly value) => PrimitiveValidationResult.Ok;
760+
}
761+
762+
// Usage examples:
763+
var myTime = new MyTime(TimeOnly.FromDateTime(DateTime.Now));
764+
765+
// Additional conversions available:
766+
DateTime dateTime = myTime; // Implicit conversion to DateTime
767+
MyTime fromDateTime = DateTime.Now; // Implicit conversion from DateTime
768+
```
769+
699770
# Disable Generation of Converters
700771

701772
To disable the generation of Converters, Swagger Mappers or XML serialization, in .csproj file follow the below described steps.
@@ -835,10 +906,10 @@ public static class Example
835906
[SupportedOperations] // no mathematical operators should be generated
836907
public readonly partial struct CustomerId : IDomainValue<int>
837908
{
838-
public static PrimitiveValidationResult Validate(decimal value)
909+
public static PrimitiveValidationResult Validate(int value)
839910
{
840-
if (value <= 0m)
841-
return "Must be a a positive number";
911+
if (value <= 0)
912+
return "Must be a positive number";
842913

843914
return PrimitiveValidationResult.Ok;
844915
}
@@ -908,8 +979,6 @@ public sealed partial class ToUpperString : IDomainValue<string>
908979

909980
// This method is automatically invoked before validation and construction.
910981
static string Transform(string value) => value.ToUpperInvariant();
911-
912-
public ToUpperString(string value) : this(Transform(value), true) { }
913982
}
914983
```
915984

0 commit comments

Comments
 (0)