### Install and Use Community Templates
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Install the community templates package to access pre-built converters for frameworks like EF Core and Dapper.
```bash
dotnet add package StronglyTypedId.Templates --version 1.0.0-beta08
```
```csharp
using StronglyTypedIds;
// Full templates include: TypeConverter, System.Text.Json, Newtonsoft.Json,
// EF Core ValueConverter, and Dapper TypeHandler
[StronglyTypedId("guid-full")]
public partial struct GuidId { }
[StronglyTypedId("int-full")]
public partial struct IntId { }
[StronglyTypedId("long-full")]
public partial struct LongId { }
[StronglyTypedId("string-full")]
public partial struct StringId { }
[StronglyTypedId("nullablestring-full")]
public partial struct NullableStringId { }
// MassTransit NewId support
[StronglyTypedId("newid-full")]
public partial struct NewIdBasedId { }
// Mix built-in template with community add-ons
[StronglyTypedId(Template.Guid, "guid-efcore")] // Built-in + EF Core only
[StronglyTypedId(Template.Int, "int-dapper")] // Built-in + Dapper only
[StronglyTypedId(Template.Long, "long-newtonsoftjson")] // Built-in + Newtonsoft only
// Available standalone templates:
// - guid-dapper, guid-efcore, guid-newtonsoftjson
// - int-dapper, int-efcore, int-newtonsoftjson
// - long-dapper, long-efcore, long-newtonsoftjson
// - string-dapper, string-efcore, string-newtonsoftjson
```
--------------------------------
### Install StronglyTypedId via CLI
Source: https://github.com/andrewlock/stronglytypedid/blob/master/README.md
Use the dotnet CLI to add the NuGet package to your project.
```bash
dotnet add package StronglyTypedId --version 1.0.0-beta08
```
--------------------------------
### Install StronglyTypedId Package
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Methods for adding the library to a .NET project via CLI or project file.
```bash
dotnet add package StronglyTypedId --version 1.0.0-beta08
```
```xml
Exe
net7.0
```
--------------------------------
### CS0436 Warning Example
Source: https://github.com/andrewlock/stronglytypedid/blob/master/README.md
Example of the compiler warning generated when type conflicts occur due to internal attribute duplication.
```bash
warning CS0436: The type 'StronglyTypedIdImplementations' in 'StronglyTypedIds\StronglyTypedIds.StronglyTypedIdGenerator\StronglyTypedIdImplementations.cs' conflicts with the imported type 'StronglyTypedIdImplementations' in 'MyProject, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
```
--------------------------------
### StronglyTypedId Parsing and Formatting Examples
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Demonstrates basic parsing, span-based parsing, TryParse, and IFormattable formatting for strongly-typed IDs. Ensure the necessary types are defined with the [StronglyTypedId] attribute.
```csharp
using StronglyTypedIds;
[StronglyTypedId]
public partial struct OrderId { }
[StronglyTypedId(Template.Int)]
public partial struct ProductId { }
// Basic parsing
var orderId = OrderId.Parse("550e8400-e29b-41d4-a716-446655440000");
var productId = ProductId.Parse("42");
Console.WriteLine(orderId.Value); // Output: 550e8400-e29b-41d4-a716-446655440000
Console.WriteLine(productId.Value); // Output: 42
// Span-based parsing (.NET 6+)
ReadOnlySpan guidSpan = "550e8400-e29b-41d4-a716-446655440000";
var fromSpan = OrderId.Parse(guidSpan);
// TryParse with provider (.NET 7+)
if (OrderId.TryParse("550e8400-e29b-41d4-a716-446655440000", provider: null, out var parsed))
{
Console.WriteLine($"Parsed: {parsed}");
}
// IFormattable - custom format strings
var id = new OrderId(Guid.Parse("550e8400-e29b-41d4-a716-446655440000"));
Console.WriteLine(id.ToString("N", null)); // Output: 550e8400e29b41d4a716446655440000
Console.WriteLine(id.ToString("B", null)); // Output: {550e8400-e29b-41d4-a716-446655440000}
Console.WriteLine(id.ToString("D", null)); // Output: 550e8400-e29b-41d4-a716-446655440000
// TryFormat for span-based formatting (.NET 6+)
Span buffer = stackalloc char[36];
if (id.TryFormat(buffer, out int charsWritten, "D"))
{
Console.WriteLine(buffer[..charsWritten].ToString());
}
// UTF-8 formatting (.NET 8+)
Span utf8Buffer = stackalloc byte[36];
if (id.TryFormat(utf8Buffer, out int bytesWritten, "D", provider: null))
{
Console.WriteLine(System.Text.Encoding.UTF8.GetString(utf8Buffer[..bytesWritten]));
}
// Generic parsing constraints (.NET 7+)
T ParseId(string value) where T : IParsable
{
return T.Parse(value, null);
}
var genericParsed = ParseId("550e8400-e29b-41d4-a716-446655440000");
```
--------------------------------
### TypeConverter Implementation
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Handles conversion between MyId, Guid, and string types for UI and data binding scenarios.
```APIDOC
## TypeConverter Conversion Logic
### Description
Provides methods to convert MyId to and from Guid or string types, enabling compatibility with standard .NET type descriptors.
### Methods
- **CanConvertFrom**: Checks if the source type (Guid or string) can be converted to MyId.
- **ConvertFrom**: Performs the conversion from Guid or string to MyId.
- **CanConvertTo**: Checks if MyId can be converted to the destination type (Guid or string).
- **ConvertTo**: Performs the conversion from MyId to the destination type.
```
--------------------------------
### Implement TryFormat for StronglyTypedId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateVeryNestedIdInFileScopeNamespace.verified.txt
This implementation uses the StringSyntax attribute for GUID formatting and writes the value to a destination span.
```csharp
[global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)]
global::System.ReadOnlySpan format,
global::System.IFormatProvider? provider)
=> Value.TryFormat(utf8Destination, out bytesWritten, format);
#endif
}
}
}
}
}
```
--------------------------------
### Configure Backing Types with Template Enum
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Specifying different primitive backing types like Guid, Int, Long, or String for the generated ID.
```csharp
using StronglyTypedIds;
// Guid-backed ID (default)
[StronglyTypedId(Template.Guid)]
public partial struct GuidId { }
// Integer-backed ID
[StronglyTypedId(Template.Int)]
public partial struct IntId { }
// Long-backed ID
[StronglyTypedId(Template.Long)]
public partial struct LongId { }
// String-backed ID
[StronglyTypedId(Template.String)]
public partial struct StringId { }
// Usage examples
var guidId = GuidId.New();
Console.WriteLine(guidId.Value); // Output: 3fa85f64-5717-4562-b3fc-2c963f66afa6
var intId = new IntId(42);
Console.WriteLine(intId.Value); // Output: 42
Console.WriteLine(IntId.Empty.Value); // Output: 0
var longId = new LongId(9223372036854775807);
Console.WriteLine(longId.Value); // Output: 9223372036854775807
var stringId = new StringId("user-123");
Console.WriteLine(stringId.Value); // Output: user-123
// Comparison operators work for all types
var id1 = new IntId(10);
var id2 = new IntId(20);
Console.WriteLine(id1 < id2); // Output: True
Console.WriteLine(id1 >= id2); // Output: False
```
--------------------------------
### Configure backing field types
Source: https://github.com/andrewlock/stronglytypedid/blob/master/README.md
Specify the backing type for an ID using the Template enum or use the default Guid type.
```csharp
using StronglyTypedIds;
[StronglyTypedId]
public partial struct FooId { }
var id = new FooId(Guid.NewGuid());
```
```csharp
using StronglyTypedIds;
[StronglyTypedId(Template.Int)]
public partial struct FooId { }
var id = new FooId(123);
```
--------------------------------
### Parsing and TryParsing GUIDs to MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Provides static methods to parse a ReadOnlySpan into a MyId object, with a TryParse overload for safe parsing. These methods delegate to the underlying System.Guid parsing methods.
```APIDOC
## Parse and TryParse MyId from Span
### Description
These methods allow parsing a character span into a `MyId` object. `Parse` throws an exception on failure, while `TryParse` returns a boolean indicating success or failure.
### Methods
#### `public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider)`
Parses a span of characters into a `MyId` object.
#### `public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result)`
Attempts to parse a span of characters into a `MyId` object. Returns `true` if successful, `false` otherwise.
### Implementation Notes
- Leverages `global::System.Guid.Parse` and `global::System.Guid.TryParse`.
- Conditional compilation (`#if NET7_0_OR_GREATER`) is used for .NET 7+ specific overloads and features.
```
--------------------------------
### Create a custom template using Roslyn CodeFix
Source: https://github.com/andrewlock/stronglytypedid/blob/master/README.md
When a custom template specified in [StronglyTypedId] does not exist, the Roslyn CodeFix provider can help create it. The generated template's backing type (Guid, int, long, or string) is inferred from the template name.
```csharp
[StronglyTypedId("some-int")] // does not exist
public partial struct MyStruct { }
```
--------------------------------
### Configure Project Reference
Source: https://github.com/andrewlock/stronglytypedid/blob/master/README.md
Add the PackageReference to your .csproj file with appropriate assets configuration to prevent runtime dependency issues.
```xml
Exe
net6.0
```
--------------------------------
### Configure EF Core with StronglyTypedId
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Demonstrates manual ValueConverter configuration and the recommended .NET 6+ convention-based approach for EF Core.
```csharp
using Microsoft.EntityFrameworkCore;
using StronglyTypedIds;
// Use templates with EF Core support
[StronglyTypedId("guid-full")]
public partial struct OrderId { }
[StronglyTypedId("int-full")]
public partial struct ProductId { }
public class Order
{
public OrderId Id { get; set; }
public string CustomerName { get; set; }
}
public class Product
{
public ProductId Id { get; set; }
public string Name { get; set; }
public decimal Price { get; set; }
}
// DbContext with manual converter configuration
public class AppDbContext : DbContext
{
public DbSet Orders { get; set; }
public DbSet Products { get; set; }
public AppDbContext(DbContextOptions options) : base(options) { }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity(builder =>
{
builder.Property(x => x.Id)
.HasConversion(new OrderId.EfCoreValueConverter())
.ValueGeneratedNever();
});
modelBuilder.Entity(builder =>
{
builder.Property(x => x.Id)
.HasConversion(new ProductId.EfCoreValueConverter())
.ValueGeneratedNever();
});
}
}
// .NET 6+ Convention-based configuration (recommended)
public class ConventionDbContext : DbContext
{
public DbSet Orders { get; set; }
public DbSet Products { get; set; }
public ConventionDbContext(DbContextOptions options) : base(options) { }
protected override void ConfigureConventions(ModelConfigurationBuilder configurationBuilder)
{
// Apply converters globally for all properties of these types
configurationBuilder.Properties()
.HaveConversion();
configurationBuilder.Properties()
.HaveConversion();
}
}
// Usage
using var context = new AppDbContext(options);
context.Database.EnsureCreated();
var order = new Order { Id = OrderId.New(), CustomerName = "Alice" };
context.Orders.Add(order);
await context.SaveChangesAsync();
var retrieved = await context.Orders.FirstAsync();
Console.WriteLine(retrieved.Id == order.Id); // Output: True
```
--------------------------------
### MyId Struct
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateDefaultIdInGlobalNamespace.verified.txt
Represents a strongly-typed identifier with a GUID value, including comparison, equality, and formatting capabilities.
```APIDOC
## MyId Struct
### Description
A strongly-typed identifier struct that wraps a System.Guid. It provides methods for creating new IDs, checking for empty IDs, and implementing comparison and equality logic.
### Type
struct MyId
### Properties
- **Value** (System.Guid) - The underlying GUID value of the identifier.
### Methods
- **New()** - Creates a new instance of MyId with a new GUID.
- **Equals(MyId other)** - Checks if this MyId is equal to another MyId.
- **GetHashCode()** - Returns the hash code for this MyId.
- **ToString()** - Returns the string representation of the underlying GUID.
- **CompareTo(MyId other)** - Compares this MyId with another MyId.
### Operators
- **== (MyId a, MyId b)** - Checks for equality between two MyId instances.
- **!= (MyId a, MyId b)** - Checks for inequality between two MyId instances.
- **> (MyId a, MyId b)** - Checks if the first MyId is greater than the second.
- **< (MyId a, MyId b)** - Checks if the first MyId is less than the second.
- **>= (MyId a, MyId b)** - Checks if the first MyId is greater than or equal to the second.
- **<= (MyId a, MyId b)** - Checks if the first MyId is less than or equal to the second.
### Constants
- **Empty** (MyId) - Represents an empty MyId with a GUID.Empty value.
### Interfaces Implemented
- System.IComparable
- System.IEquatable
- System.IFormattable
- System.ISpanFormattable (NET6_0_OR_GREATER)
- System.IParsable (NET7_0_OR_GREATER)
- System.ISpanParsable (NET7_0_OR_GREATER)
- System.IUtf8SpanFormattable (NET8_0_OR_GREATER)
```
--------------------------------
### TryParse string to MyId with provider (NET7_0_OR_GREATER)
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt
Implements IParsable for MyId, providing a TryParse method that accepts a format provider. Returns true if parsing is successful, false otherwise. Requires .NET 7.0 or later.
```csharp
public static bool TryParse(
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input,
global::System.IFormatProvider? provider,
out MyId result)
{
if (input is null)
{
result = default;
return false;
}
if (int.TryParse(input, provider, out var value))
{
result = new(value);
return true;
}
result = default;
return false;
}
```
--------------------------------
### MyIdSystemTextJsonConverter for System.Text.Json
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateIdInFileScopedNamespace.verified.txt
This JSON converter enables System.Text.Json to serialize and deserialize MyId types directly to and from GUIDs.
```csharp
public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter
{
public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());
```
--------------------------------
### Parse string to MyId with provider (NET7_0_OR_GREATER)
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt
Implements IParsable for MyId, allowing parsing from a string with a specified format provider. Requires .NET 7.0 or later.
```csharp
public static MyId Parse(string input, global::System.IFormatProvider? provider)
=> new(int.Parse(input, provider));
```
--------------------------------
### Dapper Type Handler for MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateForCustomTemplate.verified.txt
Handles the conversion of MyId to and from database types for Dapper. It supports GUID and string representations.
```csharp
public partial class DapperTypeHandler : global::Dapper.SqlMapper.TypeHandler
{
public override void SetValue(global::System.Data.IDbDataParameter parameter, MyId value)
{
parameter.Value = value.Value.ToGuid();
}
public override MyId Parse(object value)
{
return value switch
{
global::System.Guid guidValue => new MyId(global::MassTransit.NewId.FromGuid(guidValue)),
string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(global::MassTransit.NewId.FromGuid(result)),
_ => throw new global::System.InvalidCastException($"Unable to cast object of type {value.GetType()} to MyId"),
};
}
}
```
--------------------------------
### MyId Structure Definition
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleIdsWithSameName.verified.txt
The MyId structure provides a strongly-typed wrapper around a Guid, including support for comparison, equality, and serialization.
```APIDOC
## MyId Structure
### Description
Represents a strongly-typed identifier based on a System.Guid. It includes built-in support for TypeConverter and System.Text.Json serialization.
### Properties
- **Value** (Guid) - The underlying Guid value.
### Methods
- **New()** (MyId) - Creates a new MyId with a random Guid.
- **Empty** (MyId) - Returns a MyId instance with an empty Guid.
- **Equals(MyId other)** (bool) - Compares two MyId instances for equality.
- **CompareTo(MyId other)** (int) - Compares the underlying Guid values.
### Converters
- **MyIdTypeConverter** - Handles conversion between MyId, Guid, and string types.
- **MyIdSystemTextJsonConverter** - Handles JSON serialization and deserialization for MyId.
```
--------------------------------
### TryFormat Implementation
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleIdsWithSameName.verified.txt
This snippet shows the implementation of the TryFormat method for a strongly typed ID. It is used to format the ID into a UTF-8 byte array.
```csharp
global::System.IFormatProvider? provider)
=> Value.TryFormat(utf8Destination, out bytesWritten, format);
#endif
}
}
```
--------------------------------
### Parsing and Formatting
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Static methods for parsing strings into MyId and formatting MyId instances.
```APIDOC
## Parsing and Formatting
### Description
Provides static parsing capabilities and string formatting support for MyId.
### Methods
- **Parse(string)**: Parses a string into a MyId.
- **Parse(string, IFormatProvider)**: (NET7+) Parses a string with format provider support.
- **TryParse**: (NET7+) Attempts to parse a string into a MyId without throwing exceptions.
- **ToString**: Formats the MyId value using standard Guid formatting rules.
```
--------------------------------
### Parse string to MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanOverrideDefaultsWithCustomTemplateUsingGlobalAttribute.verified.txt
Parses a string representation into a `MyId` object. This method expects the input string to be a valid GUID format.
```csharp
public static MyId Parse(string input)
=> new(global::MassTransit.NewId.FromGuid(global::System.Guid.Parse(input)));
```
--------------------------------
### Define and Apply Custom Templates
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Create custom .typedid files to generate additional code and apply them using the StronglyTypedId attribute.
```csharp
// 1. Create a file named "guid-efcore.typedid" in your project
// 2. Set Build Action to "AdditionalFiles" or "C# analyzer additional file"
// guid-efcore.typedid content:
partial struct PLACEHOLDERID
{
public partial class EfCoreValueConverter :
global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter
{
public EfCoreValueConverter() : this(null) { }
public EfCoreValueConverter(
global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ConverterMappingHints? mappingHints = null)
: base(
id => id.Value,
value => new PLACEHOLDERID(value),
mappingHints
) { }
}
}
// Use the custom template
[StronglyTypedId(Template.Guid, "guid-efcore")]
public partial struct OrderId { }
// Combine multiple templates
[StronglyTypedId(Template.Guid, "guid-efcore", "guid-dapper")]
public partial struct ProductId { }
// Use only custom templates (no built-in template)
[StronglyTypedId("my-custom-guid")]
public partial struct CustomId { }
// Set custom templates as project defaults
[assembly: StronglyTypedIdDefaults(Template.Guid, "guid-efcore", "guid-dapper")]
[StronglyTypedId] // Uses Guid + guid-efcore + guid-dapper templates
public partial struct DefaultId { }
```
--------------------------------
### Parse String to MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt
Static method to parse a string representation into a MyId object. Requires the input string to be a valid GUID format.
```csharp
public static MyId Parse(string input)
=> new(global::System.Guid.Parse(input));
```
--------------------------------
### Define a custom template
Source: https://github.com/andrewlock/stronglytypedid/blob/master/README.md
Create a .typedid file using PLACEHOLDERID to define custom logic, such as EF Core value converters.
```csharp
partial struct PLACEHOLDERID
{
public class EfCoreValueConverter : global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter
{
public EfCoreValueConverter() : this(null) { }
public EfCoreValueConverter(global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ConverterMappingHints? mappingHints = null)
: base(
id => id.Value,
value => new PLACEHOLDERID(value),
mappingHints
) { }
}
}
```
--------------------------------
### Configure Project-Wide Defaults with StronglyTypedIdDefaults
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Use the assembly attribute to define a default backing type for all IDs in the project. Specific IDs can override this default by providing a template in the attribute.
```csharp
using StronglyTypedIds;
// Set project-wide defaults (place in any file, typically AssemblyInfo.cs or GlobalUsings.cs)
[assembly: StronglyTypedIdDefaults(Template.Int)]
// These IDs now use int backing type by default
[StronglyTypedId]
public partial struct OrderId { } // Uses int (from defaults)
[StronglyTypedId]
public partial struct UserId { } // Uses int (from defaults)
[StronglyTypedId]
public partial struct CustomerId { } // Uses int (from defaults)
// Override defaults for specific IDs
[StronglyTypedId(Template.Guid)]
public partial struct CorrelationId { } // Uses Guid (overrides default)
// Usage
var orderId = new OrderId(1001);
var userId = new UserId(42);
var correlationId = CorrelationId.New();
Console.WriteLine(orderId.Value); // Output: 1001
Console.WriteLine(userId.Value); // Output: 42
Console.WriteLine(correlationId.Value); // Output: 3fa85f64-5717-4562-b3fc-2c963f66afa6
```
--------------------------------
### Formatting MyId to Utf8Span
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Implements the IUtf8SpanFormattable interface for efficient UTF-8 formatting into a byte span. This method delegates to the underlying GUID formatting.
```APIDOC
## Formatting MyId to Utf8Span
### Description
This method formats the `MyId` object into a UTF-8 byte span, suitable for high-performance scenarios. It delegates to the underlying GUID formatting.
### Method
#### `public bool TryFormat(global::System.Span utf8Destination, out int bytesWritten, [global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)] global::System.ReadOnlySpan format, global::System.IFormatProvider? provider)`
Attempts to format the `MyId` object into the provided UTF-8 destination span.
### Parameters
- **utf8Destination** (`global::System.Span`)
- The span to write the formatted UTF-8 bytes to.
- **bytesWritten** (`out int`)
- When this method returns, contains the number of bytes written to `utf8Destination`.
- **format** (`global::System.ReadOnlySpan`)
- Optional format specifier for the GUID.
- **provider** (`global::System.IFormatProvider?`)
- An object that provides culture-specific formatting information.
### Implementation Notes
- Leverages `Value.TryFormat` (where `Value` is the underlying `System.Guid`).
- Conditional compilation (`#if NET8_0_OR_GREATER`) is used for .NET 8+ specific features.
```
--------------------------------
### IParsable implementation
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/UnknownTemplateCodeFixProviderUnitTests.UsesBuiltInTemplates_String.verified.txt
Implements the IParsable interface for parsing PLACEHOLDERID from a string with an optional format provider.
```csharp
public static PLACEHOLDERID Parse(string input, global::System.IFormatProvider? provider)
=> new(input);
```
```csharp
public static bool TryParse(
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input,
global::System.IFormatProvider? provider,
out PLACEHOLDERID result)
{
if (input is null)
{
result = default;
return false;
}
result = new(input);
return true;
}
```
--------------------------------
### Formatting MyId to Span
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Implements the ISpanFormattable interface to format the MyId object into a character span. This method delegates to the underlying GUID formatting.
```APIDOC
## Formatting MyId to Span
### Description
This method formats the `MyId` object into a character span, allowing for custom formatting using standard GUID format specifiers.
### Method
#### `public bool TryFormat(global::System.Span destination, out int charsWritten, global::System.ReadOnlySpan format, global::System.IFormatProvider? provider)`
Attempts to format the `MyId` object into the provided destination span.
### Parameters
- **destination** (`global::System.Span`)
- The span to write the formatted string to.
- **charsWritten** (`out int`)
- When this method returns, contains the number of characters written to `destination`.
- **format** (`global::System.ReadOnlySpan`)
- Optional format specifier for the GUID.
- **provider** (`global::System.IFormatProvider?`)
- An object that provides culture-specific formatting information.
### Implementation Notes
- Leverages `Value.TryFormat` (where `Value` is the underlying `System.Guid`).
- Conditional compilation (`#if NET7_0_OR_GREATER`) is used for .NET 7+ specific attributes like `StringSyntaxAttribute`.
```
--------------------------------
### IParsable implementation for PLACEHOLDERID
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/UnknownTemplateCodeFixProviderUnitTests.UsesBuiltInTemplates_Int.verified.txt
Implements the IParsable interface for parsing PLACEHOLDERID from strings with an optional format provider. Requires .NET 7.0 or later.
```csharp
public static PLACEHOLDERID Parse(string input, global::System.IFormatProvider? provider)
=> new(int.Parse(input, provider));
```
```csharp
public static bool TryParse(
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input,
global::System.IFormatProvider? provider,
out PLACEHOLDERID result)
{
if (input is null)
{
result = default;
return false;
}
if (int.TryParse(input, provider, out var value))
{
result = new(value);
return true;
}
result = default;
return false;
}
```
--------------------------------
### ToString with format and provider (IFormattable)
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNonDefaultIdInNamespace.verified.txt
Implements IFormattable for MyId, allowing the ID to be formatted as a string using a specified format and format provider.
```csharp
public string ToString(
#if NET7_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.NumericFormat)]
#endif
string? format,
global::System.IFormatProvider? formatProvider)
=> Value.ToString(format, formatProvider);
```
--------------------------------
### EF Core Value Converter for MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateForCustomTemplate.verified.txt
Provides a value converter for Entity Framework Core to map MyId to and from GUIDs. It can be configured with mapping hints.
```csharp
public partial class EfCoreValueConverter : global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ValueConverter
{
public EfCoreValueConverter() : this(null) { }
public EfCoreValueConverter(global::Microsoft.EntityFrameworkCore.Storage.ValueConversion.ConverterMappingHints? mappingHints = null)
: base(
id => id.Value.ToGuid(),
value => new MyId(global::MassTransit.NewId.FromGuid(value)),
mappingHints
) { }
}
```
--------------------------------
### Implement Parsing and Formatting
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateVeryNestedIdInFileScopeNamespace.verified.txt
Methods for parsing strings and spans into MyId, and formatting MyId to strings or spans, with support for .NET 7+ IParsable and ISpanParsable interfaces.
```csharp
public static MyId Parse(string input)
=> new(global::System.Guid.Parse(input));
#if NET7_0_OR_GREATER
///
public static MyId Parse(string input, global::System.IFormatProvider? provider)
=> new(global::System.Guid.Parse(input, provider));
///
public static bool TryParse(
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input,
global::System.IFormatProvider? provider,
out MyId result)
{
if (input is null)
{
result = default;
return false;
}
if (global::System.Guid.TryParse(input, provider, out var guid))
{
result = new(guid);
return true;
}
else
{
result = default;
return false;
}
}
#endif
///
public string ToString(
#if NET7_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)]
#endif
string? format,
global::System.IFormatProvider? formatProvider)
=> Value.ToString(format, formatProvider);
#if NETCOREAPP2_1_OR_GREATER
public static MyId Parse(global::System.ReadOnlySpan input)
=> new(global::System.Guid.Parse(input));
#endif
#if NET6_0_OR_GREATER
#if NET7_0_OR_GREATER
///
#endif
public static MyId Parse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider)
#if NET7_0_OR_GREATER
=> new(global::System.Guid.Parse(input, provider));
#else
=> new(global::System.Guid.Parse(input));
#endif
#if NET7_0_OR_GREATER
///
#endif
public static bool TryParse(global::System.ReadOnlySpan input, global::System.IFormatProvider? provider, out MyId result)
{
#if NET7_0_OR_GREATER
if (global::System.Guid.TryParse(input, provider, out var guid))
#else
if (global::System.Guid.TryParse(input, out var guid))
#endif
{
result = new(guid);
return true;
}
else
{
result = default;
return false;
}
}
///
public bool TryFormat(
global::System.Span destination,
out int charsWritten,
#if NET7_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)]
#endif
global::System.ReadOnlySpan format,
global::System.IFormatProvider? provider)
=> Value.TryFormat(destination, out charsWritten, format);
///
public bool TryFormat(
global::System.Span destination,
out int charsWritten,
#if NET7_0_OR_GREATER
[global::System.Diagnostics.CodeAnalysis.StringSyntax(global::System.Diagnostics.CodeAnalysis.StringSyntaxAttribute.GuidFormat)]
#endif
global::System.ReadOnlySpan format = default)
=> Value.TryFormat(destination, out charsWritten, format);
#endif
#if NET8_0_OR_GREATER
///
public bool TryFormat(
global::System.Span utf8Destination,
out int bytesWritten,
```
--------------------------------
### System.Text.Json Converter for MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Provides a System.Text.Json converter for the MyId type, handling serialization and deserialization to and from GUIDs. This is suitable for modern .NET applications using System.Text.Json.
```csharp
public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter
{
public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());
public override void Write(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options)
=> writer.WriteStringValue(value.Value);
#if NET6_0_OR_GREATER
public override MyId ReadAsPropertyName(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new(global::System.Guid.Parse(reader.GetString() ?? throw new global::System.FormatException("The string for the MyId property was null")));
public override void WriteAsPropertyName(global::System.Text.Json.Utf8JsonWriter writer, MyId value, global::System.Text.Json.JsonSerializerOptions options)
=> writer.WritePropertyName(value.Value.ToString());
#endif
}
```
--------------------------------
### Try Parse String to MyId with Provider (NET7_0_OR_GREATER)
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateNestedIdInFileScopeNamespace.verified.txt
Attempts to parse a string into a MyId object using a specified format provider, returning a boolean indicating success. Available in .NET 7 and later.
```csharp
///
public static bool TryParse(
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input,
global::System.IFormatProvider? provider,
out MyId result)
{
if (input is null)
{
result = default;
return false;
}
if (global::System.Guid.TryParse(input, provider, out var guid))
{
result = new(guid);
return true;
}
else
{
result = default;
return false;
}
}
```
--------------------------------
### Generated StronglyTypedId Struct
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateGenericVeryNestedIdInFileScopeNamespace.verified.txt
The generated code includes a struct with a Guid value, standard equality and comparison operators, and necessary type converters for JSON and TypeDescriptor support.
```csharp
//------------------------------------------------------------------------------
//
// This code was generated by the StronglyTypedId source generator
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
//
//------------------------------------------------------------------------------
#pragma warning disable 1591 // publicly visible type or member must be documented
#nullable enable
namespace SomeNamespace
{
public partial class ParentClass where T: new()
{
internal partial record InnerClass
{
public partial struct InnerStruct
{
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("StronglyTypedId", "1.0.0-beta08")]
partial struct MyId :
#if NET6_0_OR_GREATER
global::System.ISpanFormattable,
#endif
#if NET7_0_OR_GREATER
global::System.IParsable, global::System.ISpanParsable,
#endif
#if NET8_0_OR_GREATER
global::System.IUtf8SpanFormattable,
#endif
global::System.IComparable, global::System.IEquatable, global::System.IFormattable
{
public global::System.Guid Value { get; }
public MyId(global::System.Guid value)
{
Value = value;
}
public static MyId New() => new MyId(global::System.Guid.NewGuid());
public static readonly MyId Empty = new MyId(global::System.Guid.Empty);
///
public bool Equals(MyId other) => this.Value.Equals(other.Value);
public override bool Equals(object? obj)
{
if (ReferenceEquals(null, obj)) return false;
return obj is MyId other && Equals(other);
}
public override int GetHashCode() => Value.GetHashCode();
public override string ToString() => Value.ToString();
public static bool operator ==(MyId a, MyId b) => a.Equals(b);
public static bool operator !=(MyId a, MyId b) => !(a == b);
public static bool operator > (MyId a, MyId b) => a.CompareTo(b) > 0;
public static bool operator < (MyId a, MyId b) => a.CompareTo(b) < 0;
public static bool operator >= (MyId a, MyId b) => a.CompareTo(b) >= 0;
public static bool operator <= (MyId a, MyId b) => a.CompareTo(b) <= 0;
///
public int CompareTo(MyId other) => Value.CompareTo(other.Value);
public partial class MyIdTypeConverter : global::System.ComponentModel.TypeConverter
{
public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType)
{
return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value)
{
return value switch
{
global::System.Guid guidValue => new MyId(guidValue),
string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result),
_ => base.ConvertFrom(context, culture, value),
};
}
public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType)
{
return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType);
}
public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType)
{
if (value is MyId idValue)
{
if (destinationType == typeof(global::System.Guid))
{
return idValue.Value;
}
if (destinationType == typeof(string))
{
return idValue.Value.ToString();
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
public partial class MyIdSystemTextJsonConverter : global::System.Text.Json.Serialization.JsonConverter
{
public override MyId Read(ref global::System.Text.Json.Utf8JsonReader reader, global::System.Type typeToConvert, global::System.Text.Json.JsonSerializerOptions options)
=> new (reader.GetGuid());
```
--------------------------------
### Serialize with Newtonsoft.Json
Source: https://context7.com/andrewlock/stronglytypedid/llms.txt
Use the community templates package to enable full Newtonsoft.Json support. This includes handling for nullable IDs.
```csharp
using Newtonsoft.Json;
using StronglyTypedIds;
// Use the guid-full template for complete Newtonsoft.Json support
[StronglyTypedId("guid-full")]
public partial struct OrderId { }
[StronglyTypedId("int-full")]
public partial struct ProductId { }
public class Order
{
public OrderId Id { get; set; }
public ProductId ProductId { get; set; }
public string Description { get; set; }
}
// Serialization
var order = new Order
{
Id = new OrderId(Guid.Parse("550e8400-e29b-41d4-a716-446655440000")),
ProductId = new ProductId(42),
Description = "Test order"
};
var json = JsonConvert.SerializeObject(order, Formatting.Indented);
Console.WriteLine(json);
// Output:
// {
// "Id": "550e8400-e29b-41d4-a716-446655440000",
// "ProductId": 42,
// "Description": "Test order"
// }
// Deserialization
var deserialized = JsonConvert.DeserializeObject(json);
Console.WriteLine(deserialized.Id == order.Id); // Output: True
Console.WriteLine(deserialized.ProductId.Value); // Output: 42
// Nullable ID support
public class EntityWithNullableId
{
public OrderId? OptionalId { get; set; }
}
var entity = new EntityWithNullableId { OptionalId = null };
var nullableJson = JsonConvert.SerializeObject(entity);
Console.WriteLine(nullableJson); // Output: {"OptionalId":null}
```
--------------------------------
### Try parse string with IFormatProvider to MyId (NET7_0_OR_GREATER)
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanOverrideDefaultsWithCustomTemplateUsingGlobalAttribute.verified.txt
Attempts to parse a string representation into a `MyId` object using a specified `IFormatProvider`. Returns `true` if successful, `false` otherwise. This overload is available on .NET 7.0 and later.
```csharp
///
public static bool TryParse(
[global::System.Diagnostics.CodeAnalysis.NotNullWhen(true)] string? input,
global::System.IFormatProvider? provider,
out MyId result)
{
if (input is null)
{
result = default;
return false;
}
if (global::System.Guid.TryParse(input, provider, out var guid))
{
result = new(global::MassTransit.NewId.FromGuid(guid));
return true;
}
else
{
result = default;
return false;
}
}
```
--------------------------------
### Custom Type Converter for MyId
Source: https://github.com/andrewlock/stronglytypedid/blob/master/test/StronglyTypedIds.Tests/Snapshots/StronglyTypedIdGeneratorTests.CanGenerateMultipleTemplatesWithBuiltIn.verified.txt
Implements a custom type converter for the MyId type, enabling conversion from and to Guid and string. Use this for older .NET frameworks or specific serialization scenarios.
```csharp
{
public override bool CanConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type sourceType)
{
return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
public override object? ConvertFrom(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object value)
{
return value switch
{
global::System.Guid guidValue => new MyId(guidValue),
string stringValue when !string.IsNullOrEmpty(stringValue) && global::System.Guid.TryParse(stringValue, out var result) => new MyId(result),
_ => base.ConvertFrom(context, culture, value),
};
}
public override bool CanConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Type? sourceType)
{
return sourceType == typeof(global::System.Guid) || sourceType == typeof(string) || base.CanConvertTo(context, sourceType);
}
public override object? ConvertTo(global::System.ComponentModel.ITypeDescriptorContext? context, global::System.Globalization.CultureInfo? culture, object? value, global::System.Type destinationType)
{
if (value is MyId idValue)
{
if (destinationType == typeof(global::System.Guid))
{
return idValue.Value;
}
if (destinationType == typeof(string))
{
return idValue.Value.ToString();
}
}
return base.ConvertTo(context, culture, value, destinationType);
}
}
```