-
Notifications
You must be signed in to change notification settings - Fork 4
Model mapping
A model map tells Scrinium how a type is serialized to and from a document. You register maps in
IModelMapsCollectors and, from there, on the engine's MapRegistry. Customization uses the MongoDB
driver's BsonClassMap, so if you know driver class mapping you already know most of this.
Implement IModelMapsCollector and register maps in Register, which receives the
engine:
using Etherna.Scrinium.Core;
using Etherna.Scrinium.Core.Serialization;
class CatMap : IModelMapsCollector
{
public void Register(IDbContextEngine dbContextEngine)
{
dbContextEngine.MapRegistry.AddModelMap<Cat>("cd37bafa-a36d-4b1f-815a-deb50c49d030");
}
}List your collectors on the context so they're registered at build:
protected override IEnumerable<IModelMapsCollector> ModelMapsCollectors =>
[new ModelBaseMap(), new CatMap()];Tip. With many models, discover collectors by reflection over a namespace instead of listing them by hand. One collector per aggregate keeps maps organized.
IModelMapBuilder<TModel> AddModelMap<TModel>(
string activeModelMapSchemaId,
Action<BsonClassMap<TModel>>? activeModelMapSchemaInitializer = null);-
activeModelMapSchemaId— an immutable string stamped into every document this map writes, identifying the schema that produced it (see Schema id rules); GUIDs are convenient. This is what makes Versioned schemas possible. -
The initializer receives a
BsonClassMap<TModel>(the driver's class map). Without it, Scrinium appliesAutoMap().
The returned IModelMapBuilder<TModel> is where you add secondary and fallback
schemas.
Inside the initializer you use the standard driver class-mapping API:
dbContextEngine.MapRegistry.AddModelMap<EntityModelBase<string>>(
"81dd8b35-a0af-44d9-80b4-ab7ae9844eb5",
map =>
{
map.AutoMap();
// store a string Id as an ObjectId, generated on insert
map.IdMemberMap.SetSerializer(new StringSerializer(BsonType.ObjectId))
.SetIdGenerator(new StringObjectIdGenerator());
});Common customizations: AutoMap(), MapMember(x => x.Prop) / UnmapMember(...),
GetMemberMap(x => x.Prop).SetElementName("db_name"), .SetSerializer(...),
.SetDefaultValue(...), .SetIgnoreIfNull(true). To attach a
reference serializer to a member, set it with SetSerializer here.
Dates: on each persisted date member set
map.GetMemberMap(x => x.SomeDate).SetSerializer(new DateTimeOffsetSerializer(BsonType.DateTime))
to store a plain, indexable BSON Date — with no configuration the driver default writes a
{DateTime, Ticks, Offset} document. See Domain models for the date convention.
Note. The sample names the initializer parameter
schema; it is aBsonClassMap<TModel>. We usemaphere to avoid confusion with a schema (a versioned map — see below).
Schema ids must be unique across the whole database context, not just within one map. The id
fallback is reserved for fallback schemas. A duplicate id fails fast at engine
build with a detailed ScriniumDuplicateSchemaIdException, so collisions surface at startup, never in
production data. (Reference serializer configurations are separate id
spaces and aren't part of this check.)
For a value type you'd rather serialize with your own IBsonSerializer (money as Decimal128, an
encrypted string, a domain primitive), register it with AddCustomSerializerMap instead of a class
map:
dbContextEngine.MapRegistry.AddCustomSerializerMap(new EthAddressSerializer());A custom serialized type can also key an entity, serving its Id: register the custom serializer map
before the model maps of the entities it keys. See Custom serializers for what Scrinium
provides, how to write your own, and custom serialized entity ids.
Next: Versioned schemas to evolve a type over time, References and denormalization to relate documents, or Custom serializers for member-level serialization.
Scrinium — source · issues (SCR) · GNU LGPL-3.0 · info@etherna.io
Getting started
Core concepts
Working with data
Serialization & mapping
Operations & maintenance
Advanced & reference