Generic Mongo Repository pattern implemented in .NET Core
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.