Skip to main content

Repository

What is a Repository?

In C#, a repository typically refers to a design pattern used to manage data access and storage within an application. It serves as an abstraction layer between the application's business logic and the underlying data storage, which could be a database, a web service, or any other data source. The primary purpose of a repository is to centralize and encapsulate the data access logic, promoting separation of concerns and maintainability in your codebase.

Major Aspects of a repository in C#

Abstraction:

Repositories provide a clean and consistent interface for interacting with data. They define a set of methods for performing common CRUD (Create, Read, Update, Delete) operations on data entities without exposing the underlying data storage details.

Encapsulation:

Repositories encapsulate the data access code, shielding the rest of the application from the specifics of how data is fetched or stored. This separation makes it easier to change data storage implementations without affecting the application's core logic.

Testability:

Repositories improve testability by allowing you to create mock or fake repositories for unit testing. This makes it simpler to write unit tests for our application's business logic without needing to interact with real databases or external services.

Centralization:

Repositories centralize data access logic in one place, which can lead to cleaner and more maintainable code. Developers can easily locate and modify data-related code without having to search through various parts of the application.

Here's an example on how an IRepository looks in our projects:

Search

Task<OryonContentResponse<List<FuelTypeModel>>> SearchAsync(OryonPagedRequest<FuelTypeSearchFilter> requestFilter);

Get

Task<OryonContentResponse<FuelTypeModel>> GetAsync(Guid id);

Create

Task<OryonContentResponse<FuelTypeModel>> CreateAsync(FuelTypeCreateModel data);

Update

Task<OryonContentResponse<FuelTypeModel>> UpdateAsync(FuelTypeModel data);

Delete

Task<OryonResponse> DeleteAsync(Guid id);

Mongo DB Repository

We use Mongo DB as a main database program on our projects, its a NoSQL database program, MongoDB uses JSON-like documents with optional schemas, here are some key aspects that explain it:

Data Model: To work with MongoDB, you start by defining a data model, which represents the structure of our data. This model often mirrors the schema of our documents in the MongoDB collection.

Repository Class: A repository class acts as an intermediary between our application and the MongoDB database. It provides methods for CRUD (Create, Read, Update, Delete) operations, allowing you to interact with MongoDB collections easily.

Connection Management: Establishing a connection to the MongoDB server is crucial. C# provides official MongoDB drivers and libraries that facilitate connecting to the database. These connections are typically managed as singletons to optimize performance and resource usage.

Querying: MongoDB repositories in C# support querying using LINQ (Language Integrated Query) or the MongoDB Query Language. This allows you to filter, sort, and project data from the database efficiently.

Mapping: Object-Document Mapping (ODM) or Object-Relational Mapping (ORM) libraries can be used to map C# objects to MongoDB documents and vice versa. Popular libraries like MongoDB .NET Driver provide these capabilities, making it easier to work with complex data structures.

Asynchronous Operations: Asynchronous programming is essential for database interactions to prevent blocking the main thread of our application. C# and MongoDB support asynchronous operations, which help maintain application responsiveness.

Error Handling and Exception Management: Proper error handling and exception management are essential in MongoDB repositories to handle issues like network errors, timeouts, and validation failures gracefully.

Here's how a Mongo DB Repository Create Method looks in our Projects

public async Task<OryonContentResponse<FuelTypeModel>> CreateAsync(FuelTypeCreateModel data)
{
try
{
FuelTypeModel insertData = new()
{
TenantId = CurrentTenantId,
Company = data.Company,
Id = Guid.NewGuid(),
Name = new()
{
Neutral = data.Name,
Locales = new()
}
};
insertData.HandleCreated(CurrentUserReference);

await FuelTypeCollection.InsertOneAsync(insertData);
return await GetAsync(insertData.Id);
}
catch (Exception ex)
{
Logger.LogCritical(ex, nameof(CreateAsync));
return new OryonContentResponse<FuelTypeModel>()
.AddErrorToResponseModel(ex)
.SetFailed();
};
}

Conclusion

Repositories in C# are a valuable pattern for managing data access by abstracting and encapsulating the underlying storage details, which improves code organization, testability, and maintainability in our applications.