Skip to content

Defining conventions

Sometimes you will require that a given runtime type is mapped in a particular way to the database, e.g. defining the desired precision for decimal type properties or when using a custom struct defined in the model that cannot be understood by the database.

This is achieved in the Suite Framework by implementing IModelConventionContributor{TDbContext} interface, where TDbContext is the SuiteDbContext of your microservice (the one you want to apply conventions to). Implementing this interface will require you to implement a ContributeToModel method where you can define the conventions you need.

Note

You should always create a new contributor for each type you want to customize in order to keep your persistance layer clean.

C#
1
2
3
4
5
6
7
public class DecimalToDoubleConventionContributor : IModelConventionContributor<MyDbContext>
{
    public void ContributeToModel(ModelConfigurationBuilder builder)
    {
        builder.Properties<decimal>().HaveConversion<double>();
    }
}

The above code will apply a convention that maps all properties of type decimal to double when persisted to the database.

Note that some conversions are pre-defined by Entity Framework (you can check these conversions here). In case these built-in converters do not satisfy your requirements, you will need to define your own conversion strategy when calling HaveConversion() method.

In case you need to configure a convention for a specific database provider, you can instead implement BaseModelConventionContributor{TDbContext} which receives the current database provider key from DI.

Conventions hierarchy

Mapping conventions can be applied at different levels with different impact in terms of granularity. In general, we can identify the following:

  • At Framework Module level: It is done by implementing IModelConventionContributor (notice the absence of generic parameter) which will apply the specified conversion to all SuiteDbContext implementations.
  • At DbContext level: by implementing IModelConventionContributor{TDbContext}, will apply conversions to all entity types related to the specified DbContext.
  • At Entity Type level: you can specify that a particular property of your entity has a specific conversion, like:
C#
public class MyEntityTypeConfiguration : IEntityTypeConfiguration<MyDbContext, MyEntity>
{
    public void Configure(EntityTypeBuilder<MyEntity> builder)
    {
        builder.HasKey(c => c.CorrelationId);
        builder.Property(c => c.CorrelationId);
        builder.Property(c => c.Value).HasConversion<long>().HasPrecision(2);
        builder.Property(c => c.Date);
    }
}

These conventions are applied in descendant order according to scope level (Framework Module > DbContext > Entity Type), meaning that each subsequent convention will override the ones previously configured for the given scope.