StronglyTypedIds have been discussed and advocated for by a couple of well-known names in the C# development community.
- Series: Using strongly-typed entity Ids to avoid primitive obsession by Andrew Lock
- Strongly typed Guid as generic struct The ‘accepted’ answer by Eric Lippert
Briefly, a StronglyTypedId is a specific instance of an abstract generic record implementing just a single Value
autoproperty. The StronglyTypedId instance replaces the traditional int or guid Id in a class design, and prevents compile-time mistakes, for example, assigning an OderId
to an OrderId
In a series of blog posts,Using C# 9 records as strongly-typed ids by Thomas Levesque, Mssr. Levesque implements custom converters of StronglyTypedIDs for serialization in System.Text.Json and in Newtonsoft, and implements converters for persisting/instantiating StronglyTypedIDs in Entity Framework 6 (EF6).
I would like to extend this work with serialization/deserialization using the ServiceStack Json serializer library, and persistence using OrmLite,
Superficially, persistence seems impossible as it is in opposition to ServiceStack’s design philosophy of “1 Poco to 1 Table”; however, the StronglyTypedID instance is simply a single Value
autoproperty. This should map to the Id
property of a Poco (and its persisted table).
I’ve done a good bit of searching in the ServiceStack OrmLite examples, to no avail. Before I spend more time on this - is it even theoretically possible to accomplish this?
public abstract record AbstractStronglyTypedId<TValue> {
// Generic Type Constraints are not able to restrict TValue to one of these four types: int, long, guid, or string[]. However, TValues other than these four can be detected at run time, and an exception raised, the very first time an improper instance of AbstractStronglyTypedId is created. This validation code is part of the constructor, and omitted for brevity.
public TValue Value {get; init;}
}
public class MyPocoId : AbstractStronglyTypedId<int> {};
public class MyPoco {
[Identity]
[Autoincrement]
public MyPocoId Id {get; init}
// constructor omitted for brevity.
}
Should map to a table named Poco
having a single column named Id
with type int
, and the data stored in the Id
column should map to the inherited autoproperty MyPocoId.Value
.
Mssr. Lavesque implements this in EF6 with an override of OnModelCreating
for every EntityType having a property that derives from StronglytypedId, adding a converter and an Id
mapping. C# 9 records as strongly-typed ids - Part 4: Entity Framework Core integration
Is this even remotely possible in ServiceStack OrmLite?