StrongTypeId prevents developer from using the wrong Id in their code.
Compatible with Asp.Net Core routing
, Entity Framework Core
, NHibernate
, System.Text.Json
, Newtonsoft.Json
, GraphQL.Net
and HotChocolate
Record idea and TypeConverters are from Thomas Levesque blog
Example :
public class Product
{
public int Id { get; set; }
}
public class Account
{
public int Id { get; set; }
}
public void CreateItem(int productId, int accountId);
// Wrong but it compiles 😨
❎ CreateItem(account.Id, product.Id);
//////////////////////////////////////////
// With StrongTypeId, you would have
//////////////////////////////////////////
public record ProductId(int Value) : StrongTypeId(Value);
public class Product
{
public ProductId Id { get; set; }
}
public record AccountId(int Value) : StrongTypeId(Value);
public class Account
{
public AccountId Id { get; set; }
}
public void CreateItem(ProductId productId, AccountId accountId);
// Will not compile 👍
❌ CreateItem(account.Id, product.Id);
Install-Package StrongTypeId
Simply declare your identifiers like this :
public record ProductId(int Value) : StrongTypeId(Value)
{
// Before C# 10 and .Net6.0
// Needed if you wanna use your StrongTypeId in route parameters
// Or you can use StrongTypeId.Generators to generate it
public override string ToString() => base.ToString();
}
And use it like that :
public class Product
{
public ProductId Id { get; set; }
}
This library is compatible with Newtonsoft.Json
and System.Text.Json
.
We provide converters that will serialize the strong type to his Id type.
Also it will deserialize Id type to strong type.
Install-Package StrongType.Newtonsoft.Json
In your Startup.cs, ConfigureServices
services.AddMvc().AddNewtonsoftJson(options =>
{
// Add StrongTypeId Converter
options.SerializerOptions.Converters.Add(new StrongTypeIdJsonConverter());
});
Install-Package StrongTypeId.System.Text.Json
In your Startup.cs, ConfigureServices
services.AddMvc()
.AddJsonOptions(options =>
{
options.JsonSerializerOptions.Converters.Add(new StrongTypeIdJsonConverterFactory());
});
This library is compatible with NHibernate. Entity Framework contribution are welcome !
Install-Package StrongTypeId.FluentNhibernate
var fluentCfg = Fluently.Configure()
.Mappings(m =>
{
m.FluentMappings.Conventions.Add<ConventionStrongTypeId>();
});
Install-Package StrongTypeId.EFCore
In your model's OnConfiguring method
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseStrongTypeIdConventions();
When using Npgsql, StrongTypeId (by default) cannot be auto-increment. We need to change Npgsql conventions to do that :
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
=> optionsBuilder
.UseCustomStrongTypeNpgsqlBuilder()
When using strong type id in your route like this :
var productId = new ProductId(5);
RedirectToAction("Index", new { id = productId });
The generated url, will use productId.ToString()
in the Url.
By default C# create a ToString()
method on record
that will display :
ProductId { Value = 5 }
And the url will look like this :
/Product/Index/ProductId { Value = 5 }
instead of /Product/Index/5
To prevent this, you have to override ToString()
or use the source generator that will do it for you.
Register specific ScalarType for GraphQL.Net
Install-Package StrongTypeId.GraphQL
Inside your Schema :
using StrongType.GraphQL;
public class MySchema : Schema
{
public MySchema(IHttpContextAccessor httpContextAccessor)
: base(httpContextAccessor.HttpContext.RequestServices)
{
this.AddStrongTypeId<ProductId>();
}
}
Install-Package StrongTypeId.HotChocolate
In your Startup.cs, ConfigureServices :
using StrongType.HotChocolate;
...
services.AddGraphQLServer()
.BindStrongTypeId<ProductId>()
or if you wanna add all types automatically :
services.AddGraphQLServer()
.BindStrongTypeInAssembly(typeof(ProductId).Assembly)
Before C# 10 and .Net6.0 the ToString method could not be sealed. So we needed a generator to create the right ToString method
Install-Package StrongTypeId.Generators
Then you must declare your record as partial :
public partial record ProductId(int Value) : StrongTypeId(Value);
And the generator will generate the ToString()
method at compilation.