Skip to main content
Version: 0.3.x (0.3.0)

Class ValueObjectBsonSchema

Namespace: AdCodicem.ValueObjects.MongoDB
Assembly: AdCodicem.ValueObjects.MongoDB.dll

Builds a $jsonSchema collection validator from the rules of the value objects a document holds, so that the server refuses a document another writer stores with a value the type rejects.

public static class ValueObjectBsonSchema

Inheritance​

object ← ValueObjectBsonSchema

Inherited Members​

object.Equals(object?), object.Equals(object?, object?), object.GetHashCode(), object.GetType(), object.MemberwiseClone(), object.ReferenceEquals(object?, object?), object.ToString()

Remarks​

A collection has no schema, and a strict read refuses, one document at a time, what another service, a script or Compass stored. A validator built here makes the server refuse it on the write instead, with code 121, "Document failed validation", naming the field and the rule:

await database.CreateCollectionAsync("orders", new CreateCollectionOptions<BsonDocument>
{
Validator = new BsonDocumentFilterDefinition<BsonDocument>(ValueObjectBsonSchema.For<Order>()),
});

Each rule is carried only where the server refuses no value the type accepts, since a validator stricter than the type would refuse the application's own writes. MaxLength becomes maxLength; MinLength becomes minLength, halved unless the pattern keeps every value in the Basic Multilingual Plane, since the server counts a character outside it as one where .NET counts two; the pattern behind becomes pattern, written in the PCRE2 dialect the server reads, a class escape listed as the characters .NET's own Unicode tables give it, when it stays within what both engines read alike and sets no option such as IgnoreCase; the bounds become minimum and maximum, written as the serializer writes a number; a closed set becomes enum, unless the type stores another spelling of a known value, as a set looked up ignoring case does; and the description becomes description. Rules only code checks, a checksum in , stay on the read path.

The document is described as its class map writes it, element names and serialization options included: a value object's bsonType is the BSON type the serializer of its underlying value writes, binData for a under the standard representation, string for one given [BsonRepresentation(BsonType.String)]. A value object member is required, unless the class map leaves it out when it is the default or null; a TSelf? is not, and adds null to its bsonType and to its enum. A document nested in a member, and the elements of an array, are described the same way, where they hold a value object. A dictionary, a member with a serializer of the application's own, and whatever holds no value object, are left free.

The server checks an update as it checks an insert, so a validator also catches what no serializer sees, such as an Update.Inc(x => x.Quantity.Value, 1) past the maximum. validationLevel and validationAction are the application's to set, beside the validator, on createCollection or collMod.

Methods​

For<TDocument>()​

Builds { "$jsonSchema": { … } } for a document type, from its class map and the rules of each value object it holds.

public static BsonDocument For<TDocument>()

Returns​

BsonDocument

The validator, to pass to createCollection or collMod.

Type Parameters​

TDocument

The type of the documents the collection holds.

Remarks​

It reads the serializer the driver gives each member, and builds the class maps of the document and of the classes nested in it, which the driver keeps for good. So call it at start-up, after , without which a value object would be given a class map; after EntityIdBson.Register, whose id generators a class map takes when it is built; and after any BsonClassMap.RegisterClassMap of those types, which fails once one is built.

Exceptions​

InvalidOperationException

has not registered its serializers yet, or the driver serializes TDocument through a serializer of its own rather than a class map.