@@ -17,6 +17,8 @@ project — there are **no runtime package references**.
1717## Core Interfaces
1818
1919``` csharp
20+ using StructId ;
21+
2022// String-backed ID
2123public readonly partial record struct ProductId : IStructId ;
2224
@@ -28,6 +30,8 @@ public readonly partial record struct OrderId : IStructId<int>;
2830### ` IStructId ` (string value)
2931
3032``` csharp
33+ namespace StructId ;
34+
3135public partial interface IStructId
3236{
3337 string Value { get ; }
@@ -37,6 +41,8 @@ public partial interface IStructId
3741### ` IStructId<TValue> ` (struct value)
3842
3943``` csharp
44+ namespace StructId ;
45+
4046public partial interface IStructId <TValue > where TValue : struct
4147{
4248 TValue Value { get ; }
@@ -48,6 +54,8 @@ public partial interface IStructId<TValue> where TValue : struct
4854Static interface members for consistent factory methods:
4955
5056``` csharp
57+ namespace StructId ;
58+
5159public interface INewable <TSelf >
5260{
5361 static abstract TSelf New (string value );
@@ -72,6 +80,8 @@ T CreateId<T, V>(V value) where T : INewable<T, V> => T.New(value);
7280The minimum declaration is a ` readonly partial record struct ` implementing one of the core interfaces:
7381
7482``` csharp
83+ using StructId ;
84+
7585public readonly partial record struct UserId : IStructId <Guid >;
7686public readonly partial record struct ProductId : IStructId ; // string-backed
7787public readonly partial record struct OrderId : IStructId <int >;
@@ -85,6 +95,8 @@ public readonly partial record struct TraceId : IStructId<Ulid>; // Ulid suppo
8595- If you declare a primary constructor, it must have a single parameter named ` Value `
8696
8797``` csharp
98+ using StructId ;
99+
88100// Custom primary constructor (e.g. to add attributes)
89101public readonly partial record struct ProductId ([property : JsonPropertyName (" id" )] int Value ) : IStructId <int >;
90102```
@@ -195,6 +207,8 @@ or members. Templates are regular C# files in your project.
195207** Apply to all struct IDs (any value type):**
196208
197209``` csharp
210+ using StructId ;
211+
198212[TStructId ]
199213file partial record struct TSelf (TValue Value )
200214{
@@ -208,6 +222,8 @@ file record struct TValue; // empty = match any value type
208222** Apply only to string-backed IDs:**
209223
210224``` csharp
225+ using StructId ;
226+
211227[TStructId ]
212228file partial record struct TSelf (string Value )
213229{
@@ -219,6 +235,8 @@ file partial record struct TSelf(string Value)
219235** Apply only to Guid-backed IDs:**
220236
221237``` csharp
238+ using StructId ;
239+
222240[TStructId ]
223241file partial record struct TSelf (Guid Value ) : IMyGuidId
224242{
@@ -229,6 +247,8 @@ file partial record struct TSelf(Guid Value) : IMyGuidId
229247** Apply to IDs whose value type implements a specific interface:**
230248
231249``` csharp
250+ using StructId ;
251+
232252[TStructId ]
233253file partial record struct TSelf (TValue Value ) : IComparable <TSelf >
234254{
@@ -250,6 +270,8 @@ file record struct TValue : IComparable<TValue>
250270** Exclude string from TValue matching:**
251271
252272``` csharp
273+ using StructId ;
274+
253275// /*!string*/ inline comment excludes string-backed IDs
254276 [TStructId ]
255277file partial record struct TSelf (/* !string*/ TValue Value )
@@ -263,6 +285,8 @@ file record struct TValue;
263285** Add TSelf interface constraint (additional filtering):**
264286
265287``` csharp
288+ using StructId ;
289+
266290[TStructId ]
267291file partial record struct TSelf (Ulid Value )
268292{
@@ -293,6 +317,8 @@ For a struct ID `PersonId : IStructId<Guid>` and a template applying to `Guid`-b
293317To generate unique helper type names per struct ID, use the ` TSelf_ ` or ` TValue_ ` prefix:
294318
295319``` csharp
320+ using StructId ;
321+
296322[TStructId ]
297323file partial record struct TSelf (TValue Value )
298324{
@@ -308,6 +334,8 @@ file record struct TValue;
308334For custom Dapper handlers or EF Core converters for a specific value type, use ` [TValue] ` :
309335
310336``` csharp
337+ using StructId ;
338+
311339[TValue ]
312340file class TValue_Handler : SqlMapper .TypeHandler <TValue >
313341{
@@ -363,6 +391,8 @@ No attribute, configuration, or code change is needed — just add the NuGet ref
363391### Entity with typed ID in EF Core
364392
365393``` csharp
394+ using StructId ;
395+
366396public readonly partial record struct UserId : IStructId <Guid >;
367397
368398public class User
@@ -391,6 +421,8 @@ var options = new DbContextOptionsBuilder<AppDbContext>()
391421### Dapper query with struct ID
392422
393423``` csharp
424+ using StructId ;
425+
394426public readonly partial record struct ProductId : IStructId <int >;
395427
396428using var connection = new SqliteConnection (" Data Source=app.db" );
@@ -405,6 +437,8 @@ var product = connection.QueryFirst<Product>(
405437### Generic repository using INewable
406438
407439``` csharp
440+ using StructId ;
441+
408442public class Repository <TEntity , TId , TValue >
409443 where TId : struct , IStructId <TValue >, INewable <TId , TValue >
410444 where TValue : struct
0 commit comments