Generic Mongo Repository pattern implemented in .NET Core

Marek Żyła
4 min readDec 24, 2019

--

Jump into code

Hello, today I want to present you modern Mongo Generic Repository implemented in loved by back-end developers .NET Core, let’s jump right into the shark’s mouth! 🦈

Quick Start

Packages installation

Okay, to get started we have to prepare our environment, let’s install necessary .nuget packages, you can do it in several ways:

  • using .NET CLI
    dotnet add package MongoDB.Driver
  • using Package Manager
    Install-Package MongoDB.Driver

Mongo Db server configuration

In this article I hope you already have MongoDb server instance configured. I’m using Docker to run my MongoDb server. The most important thing is to get proper connection string while connecting to our database. My server is running on localhost:32772.

Configure Startup

Once, we have our packages installed, what we need to do, is to connect our application to Mongo database. Let’s do it!

Modify appsettings.json to provide proper connection string and create database name. I created additional JSON object containing important settings.

Now, let’s create settings class to keep clean code inStartup.cs when it comes to types registration.

Next, we have to register our MongoDb client instance in Startup.cs using previously prepared settings class. Do it before AddControllers() in ConfigureServices method.

Repository implementation

Document preparation

We’ll start our implementation by creating proper abstraction layer for our documents (entities in Mongo). I created a class and interface that contains base information about each document

As you can see, Id property has Bson attributes for configuration. It tells our Mongo Driver to treat this property as native mongoobjectId.

Collection naming

Mongo Driver lacks attribute that allows us to set the collection name for documents, so I created one.

And here is this attribute in action for our sample document

As you can see, we have a class called Person, but actual collection in database will have name of people.

Repository

Oh and that’s what you’ve been waiting for! Finally, repository pattern implemented in dotnet core. We have here interface and its implementation, I definitely suggest you putting it in separate files, because we have here a lot of methods.

This interface defines all public methods that our repository will serve. As you can see there are special methods for each CRUD operation. Below I pasted an implementation and longer description of each method.

Repository implementation explained

Constructor: it connects to our database server by MongoClient and gets the proper database by GetDatabase method. Next, we get collection data and store it in private field called _collection.

GetCollectionName: this method uses our previously prepared attribute and gets documents collection by type of document provided in parameter (ex. when we pass Person as the parameter, this method will return “people” as a result).

AsQueryable: this method let’s us to get whole non-materialized collection and perform some operations later (it’s slower than other methods because adds extra abstraction layer).

FilterBy: those methods allows us to filter data by sending expressions in parameters. This works similar to LINQ, but operations are performed on database, so it’s much faster than doing it later in code-side. I provided extra parameter called projectionExpression, this parameter is useful, when you want to get only some fields, rather than full objects from filtered results. You can also add sorting when necessary, simply using Sort method provided by IFindFluent interface.

FindOne and FindById: those methods are here to get single objects from database, I provided here also asynchronous implementations.

InsertOne and InsertMany: methods are used to insert documents to our database, also implemented in synchronous and asynchronous ways.

ReplaceOne: this method is used to replace documents in our application. You can also use Update method if you need.

DeleteOne and DeleteById: those are for hard-deleting documents in our app. When it comes to business application, i’d also suggest you using soft-delete, by simply updating some field called documentState and setting it to deleted. It’ll secure your data from being deleted by accident or some other cases.

Usage of Repository

Registering repository in Startup

As we finished implementation, the last thing to do, is to register our repository in Startup.cs in ConfigureServices method.

Usage in API

Eventually, we can use our mechanism to perform some operations in actual application. Here, I have sample controller, you should never use your repository there, but it’s just to make this article shorter. When it comes to real application, consider adding some application services to communicate with your data layer which repository belongs to.

Conclusion

That’s all for today, we implemented together Mongo Generic Repository, using MongoDb Driver. You can also make it even faster by creating correct indexes for each collection, but this is a topic for separate article.

If you appreciate my work, don’t forget to react for this story by positive feedback. I have also other interesting articles on my profile, so make sure to check them out!

Thanks.

--

--

Marek Żyła

I’m Mark, from Poland. I’m a passionate of IT, especially programming. In my free time, I produce music and skateboarding.