DEV Community

giscard
giscard

Posted on

Use class mapping to avoid decorating classes and properties with MongoDB specific attributes.

Let say we are developing a backend server for a game. The backend use c# (asp.net core) and mongodb as the database. One requirement is that WE CAN MODIFY THE DOMAIN MODEL. For example, our costumer uses the Player.cs class below in his game and ask us to save and retrieve it in the database.
We can code it like

public class Player
    {
        public string PlayerId { get; set; }
        public string Name { get; set; }

    }
Enter fullscreen mode Exit fullscreen mode

Normally if we have access to the model, we will probably add a lot of attributes to tell the database how to store data and optimize queries.
For example, to let the database know that the property PlayerId should be the primary key, we can simply add the BsonId attribute to the PlayerId property.
using MongoDB.Bson.Serialization.Attributes;

namespace Commons
{
    public class Player
    {
        [BsonId]
        public string PlayerId { get; set; }
        public string Name { get; set; }

    }
}
Enter fullscreen mode Exit fullscreen mode

We can achieve the same thing without modifying the player.cs class. For that we can use class mapping feature provided by the mongodb csharp client library.
It is very important that the registration of class maps occurs prior to them being needed. The best place to register them is at application startup prior to initializing a connection with MongoDB.
You can add the following code in program.cs

BsonClassMap.RegisterClassMap<Player>(cm =>
            {
                cm.AutoMap();
                cm.MapIdMember(c => c.PlayerId)
                    .SetIdGenerator(new StringObjectIdGenerator())
                    .SetSerializer(new StringSerializer(BsonType.ObjectId));

                cm.SetIgnoreExtraElements(true);
            });
Enter fullscreen mode Exit fullscreen mode

The code cm.AutoMap(); uses default conventions to map the class and its members.(http://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/conventions/)
the code cm.MapIdMember(c => c.PlayerId) tells the database to use the property PlayerId as the primary key.

The primary key of a mongodb document is of type ObjectId (custom type defined by mongodb), but we want our PlayerId to be a string , we tell that to the database using the code .SetIdGenerator(new StringObjectIdGenerator()) and we use the code
.SetSerializer(new StringSerializer(BsonType.ObjectId)); to convert it back to a string when we query the database.

There we go, we are able to specifically tell the database how to work with our domain model, without having to modify it. Very powerful.
There is much more we can do with class mapping in mongo db.
http://mongodb.github.io/mongo-csharp-driver/2.0/reference/bson/mapping/

Thanks

Oldest comments (1)

Collapse
 
adrielairaldo profile image
adrielairaldo

Here just to say thanks! Perfect matching with CLEAN architecture principles ;)