Repository Pattern in ASP.NET Core – Ultimate Guide

by | Updated on Jun 28, 2020 | ASP.NET Core, Design Patterns

In this extensive guide, we will go through everything you will need to know about Repository Pattern in ASP.NET Core, Generic Repository Patterns, Unit of Work and related topics. We will build a project right from scratch where we implement a clean architecture to access data. The source code of this implemenation is over at my Github.

What’s a Repository Pattern?

A Repository pattern is a design pattern that mediates data from and to the Domain and Data Access Layers ( like Entity Framework Core / Dapper). Repositories are classes that hide the logics required to store or retreive data. Thus, our application will not care about what kind of ORM we are using, as everything related to the ORM is handled within a repository layer. This allows you to have a cleaner seperation of concerns. Repository pattern is one of the heavily used Design Patterns to build cleaner solutions.

Benefits of Repository Pattern

Reduces Duplicate Queries

Imagine having to write lines of code to just fetch some data from your datastore. Now what if this set of queries are going to be used in multiple places in the application. Not very ideal to write this code over and over again, right? Here is the added advantage of Repository Classes. You could write your data access code within the Repository and call it from multiple Controllers / Libraries. Get the point?

De-couples the application from the Data Access Layer

There are quite a lot of ORMs available for ASP.NET Core. Currently the most popular one is Entity Framework Core. But that change in the upcoming years. To keep in pace with the evolving technologies and to keep our Solutions upto date, it is highly crucial to build applications that can switch over to a new DataAccessTechnology with minimal impact on our application’s code base.

There can be also cases where you need to use multiple ORMs in a single solution. Probably Dapper to fetch the data and EFCore to write the data. This is solely for performance optimizations.

Repository pattern helps us to achieve this by creating an Abstration over the DataAccess Layer. Now, you no longer have to depend on EFCore or any other ORM for your application. EFCore becomes one of your options rather than your only option to access data.

The Architecture should be independent of the Frameworks.

– Uncle Bob ( Robert Cecil Martin )

Building an Enterprise level ASP.NET Core Application would really need Repository Patterns to keep the codebase future proof for atleast the next 20-25 years (After which, probably the robots would take over πŸ˜› ).

Is Repository Pattern Dead?

This is one of the most debated topics within the .NET Core Community. Microsoft has built the Entity Framework Core using the Repository Pattern and Unit of Work Patterns. So, why do we need to add another layer of abstraction over the Entity Framework Core, which is yet another abstration of Data Access. The answer to this is also given by Microsoft.

Read more here – https://docs.microsoft.com/en-us/dotnet/architecture/microservices/microservice-ddd-cqrs-patterns/infrastructure-persistence-layer-implemenation-entity-framework-core#using-a-custom-repository-versus-using-ef-dbcontext-directly

Microsoft themselves recommend using Repository Patterns in complex scenarios to reduce the coupling and provide better Testability of your solutions. In cases where you want the simplest possible code, you would want to avoid the Repository Pattern.

custom repo versus db context
Custom Repository vs DBContext . Source : Microsoft

Adding the Repository has it’s own benefits too. But i strongly advice to not use Design Patterns everywhere. Try to use it only whenever the scenario demands the usage of a Design Pattern. That being stated, Repository pattern is something that can benefit you in the long run.

Implementing Repository Pattern in ASP.NET Core 3.1

Let’s implement Repository Pattern in an ASP.NET Core WebApi Project. What seperates this guide from the others is that we will also be working with a Clean Architecture in mind to demonstrate the real-life implementation. This means that we will be working with multiple Layers and Projects and also go through the basics of Dependency Inversion Principle.

PS, I am using Visual Studio 2019 Community as my default IDE. Read this article to install this awesome IDE on to your machine.

Let’s start by creating a new Solution. Here I am naming my Solution as RepositoryPattern.WebApi and the first project as WebApi (ASP.NET Core).

Repository Pattern in ASP.NET Core

Simalary, let’s add 2 more .NET Core Class Library Projects within the solution. We will call it DataAccess.EFCore and Domain. Here are the features and purposes of each project.

  • Domain – Holds the Entities and Interfaces. It does not depend on any other project in the solution.
  • DataAccess,EFCore – Since we will be using Entity Framework Core – Code First Apporach to interact with our Database, let’s build a project that solely represents everything related to EFCore. The aim is that, later down the road one can easily build another Data Access layer like DataAccess.Dapper or so. And our application would still support it. Here is where Dependency Inversion comes to play.
  • WebApi – This is like the presentation layer of the entire solution. It depends on both the projects.

Here is how our Solution would look like now.

project 1

Setting up the Entities and EFCore

Now, let’s add the Required Entities to the Domain Project. Create a new Folder in the Domain Project named Entities.

Create 2 very simple classes – Developer and Project under the Entities Folder.

public class Developer
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Followers { get; set; }
}
public class Project
{
    public int Id { get; set; }
    public string Name { get; set; }
}

Next , we will setup and configure Entity Framework Core. Install these Required Packages in the DataAccess.EFCore Project. Here is where we would have our DbContect Class and the actual Implementations of the Repositories.

Install-Package Microsoft.EntityFrameworkCore
Install-Package Microsoft.EntityFrameworkCore.SqlServer

Add a reference to the Domain Project (where we have defined our entities) and create a new Class in the DataAccess.EFCore Project and Name it ApplicationContext.cs.

public class ApplicationContext : DbContext
{
    public ApplicationContext(DbContextOptions<ApplicationContext> options) : base(options)
    {
    }
    public DbSet<Developer> Developers { get; set; }
    public DbSet<Project> Projects { get; set; }
}

Once our Data Access Layer is done, let’s move to the WebApi Project to register EFCore within the ASP.NET Core Application. We will also update the database in this step to accomadate the Developer and Project Table.

Firstly, Install this package on the WebApi Project. This allows you to run EF Core commands on the CLI.

Install-Package Microsoft.EntityFrameworkCore.Tools

Next, Navigate to Startup.cs and add this line to Register the ApplicationContext class that we created. Note that you will have to add a refernce of the DataAccess.EFCore Project to the WebApi Project.

services.AddDbContext<ApplicationContext>(options =>
options.UseSqlServer(
    Configuration.GetConnectionString("DefaultConnection"),
    b => b.MigrationsAssembly(typeof(ApplicationContext).Assembly.FullName)));

After that, open up the appsettings.json file in the Api Project and add the connection string.

"ConnectionStrings": {
  "DefaultConnection": "<your connection string>",
},

Finally, Let’s update the database. Open your Package Manager Console on Visual Studio and run the following commands.

add-migration Initial
update-database

Make sure that you have set your Startup Project as WebApi and the Default Project as DataAccess.EFCore. Here is a screenshot.

migrate

Ps, This is a very basic setup of Entity Framework Core. I have written a detailed Guide on Entity Framework Core – Code First Apporach. Give it a look to learn more.

Let’s Keep Repositories Away for a Moment.

Now that we have configured our EFCore Layer, let’s talk a bit about the traditional way to get data from this layer. Traditionally, you would directly call the dbContext object to read and write data. This is fine. But is it really ideal for the long run? When you use the dbContext directly, what you are doing is that, the Entity Framework Core is being tightly coupled within your application. So, Tommorow when there is something newer and better than EFCore, you would find it really annoying to implement the new tech and make the corresponding changes. Right?

One more disadvantage of directly using the dbContext directly is that you would be exposing the DbContext, which is totally insecure.

This is the reason to use Repository Pattern in ASP.NET Core Applications.

Practical Use-Case of Repositories

While Performing CRUD Operations with Entity Framework Core, you might have noticed that the basic essence of the code keeps the same. Yet we write it multiple times over and over. The CRUD Operations include Create, Read, Update, and Delete. So, why not have a class / interface setup where you can generalize each of these operations.

Building a Generic Repository

First up, let’s add a new folder Interfaces in our Domain Project. Why? Because, we will be inverting the dependencies, so that, you can define the interface in the Domain Project, but the implementation can be outside the Domain Project. In this case, the implementations will go the DataAccess.EFCore Project. Thus, your domain layer will not depends on anything, rather, the other layers tend to depend on the Domain Layer’s interface. This is a simple explanation of Dependency Inversion Principle. Pretty Cool, yeah?

Add a new interface, Interfaces/IGenericRepository.cs

public interface IGenericRepository<T> where T : class
{
    T GetById(int id);
    IEnumerable<T> GetAll();
    IEnumerable<T> Find(Expression<Func<T, bool>> expression);
    void Add(T entity);
    void AddRange(IEnumerable<T> entities);
    void Remove(T entity);
    void RemoveRange(IEnumerable<T> entities);
}

This will be a Generic Interface, that can be used for both the Developer and Project Classes. Here T is the specific class.

The set of functions depends on your preference. Ideally, we require 7 functions that cover most of the data handling part.

  1. Get’s the entity By Id.
  2. Get’s all the Record.
  3. Finds a set of record that matches the passed expression.
  4. Adds a new record to the context
  5. Add a list of records
  6. Removes a record from the context
  7. Removes a list of records.

Now, Let’s implement this Interfaces. Create a new class in the DataAccess.EFCore Project and name it Repositories/GenericRepository

public class GenericRepository<T> : IGenericRepository<T> where T : class
{
    protected readonly ApplicationContext _context;
    public GenericRepository(ApplicationContext context)
    {
        _context = context;
    }

    public void Add(T entity)
    {
        _context.Set<T>().Add(entity);
    }

    public void AddRange(IEnumerable<T> entities)
    {
        _context.Set<T>().AddRange(entities);
    }

    public IEnumerable<T> Find(Expression<Func<T, bool>> expression)
    {
        return _context.Set<T>().Where(expression);
    }

    public IEnumerable<T> GetAll()
    {
        return _context.Set<T>().ToList();
    }

    public T GetById(int id)
    {
        return _context.Set<T>().Find(id);
    }

    public void Remove(T entity)
    {
        _context.Set<T>().Remove(entity);
    }

    public void RemoveRange(IEnumerable<T> entities)
    {
        _context.Set<T>().RemoveRange(entities);
    }
}

This class will implement the IGenericRepository Interface. We will also inject the ApplicationContext here. This way we are hiding all the actions related to the dbContext object within Repository Classes. Also note that, for the ADD and Remove Functions, we just do the operation on the dbContext object. But we are not yet commiting/updating/saving the changes to the database whatsover. This is not something to be done in a Repository Class. We would need Unit of Work Pattern for these cases where you commit data to the database. We will discuss about Unit of Work in a later section.

Understood why we used a Generic Repository instead of a IDevloperRepository?? When there are large number of entites in our application, we would need seperate repositories for each entities. But we do not want to implement all of the above 7 Functions in each and every Repository Class, right? Thus we made a generic repository that holds the most commonly used implementaions.

Now what happens if we need the records of Most Popular Developers from our Database? We do not have a function for it in our Generic Class, do we ? This is where we can see the advantage of building a Generic Repository.

Inheriting and Extending the Generic Repository

In the Domain Project, under the Interfaces, add a new interface named IDeveloperRepository.

public interface IDeveloperRepository : IGenericRepository<Developer>
{
    IEnumerable<Developer> GetPopularDevelopers(int count);
}

Here we are inheriting all the Functions of the Generic Repository, as well as adding a new Funciton ‘GetPopularDevelopers’. Get it?

Let’s implement the IDeveloperRepostory. Go to the DataAccess Project and under Repositories folder, add a new class, DeveloperRepository.

public class DeveloperRepository : GenericRepository<Developer>, IDeveloperRepository
{
    public DeveloperRepository(ApplicationContext context):base(context)
    {
    }
    public IEnumerable<Developer> GetPopularDevelopers(int count)
    {
        return _context.Developers.OrderByDescending(d => d.Followers).Take(count).ToList();
    }
}

You can notice that we have not implemented all the 7 functions here, as it is is already implemented in our Generic Repository. Saves a lot of lines, yeah?

Similary, let’s create interface and implementation for ProjectRepository.

public interface IProjectRepository : IGenericRepository<Project>
{
}

Now, the implementation.

public class ProjectRepository : GenericRepository<Project>, IProjectRepository
{
    public ProjectRepository(ApplicationContext context): base(context)
    { 
    }
}

You can see that the interface and implementations are quite blank. So why create new class and interface for Project? This can also attribute to a good practice while developing applications. We also anticipate that in future, there can be functions that are spcific to the Project Entity. To support them later on, we provide with interfaces and classes. Future Proofing, yeah?

Finally, let’s register these Interfaces to the respective implementaions in the Startup.cs of the WebApi Project. Navigate to Startup.cs/ConfigureServices Method and add these lines.

#region Repositories
services.AddTransient(typeof(IGenericRepository<>), typeof(GenericRepository<>));
services.AddTransient<IDeveloperRepository, DeveloperRepository>();
services.AddTransient<IProjectRepository, ProjectRepository>();
#endregion

Unit Of Work Pattern

Unit of Work Pattern is a design pattern with which you can expose various respostiories in our application. It has very similar properties of dbContext, just that Unit of Work is not coupled to any framework like dbContext to Entity Framework Core.

Till now, we have built a couple of repositories. We can easily inject these repositories to the constructor of the Services classes and access data. This is quite easy when you have just 2 or 3 repository objects involved. What happens when there are quite more than 3 repositories. It would not be practical to keep adding new injections every now and then. Inorder to wrap all the Repositories to a Single Object, we use Unit Of Work.

Unit of Work is responsible for exposing the available Repositories and to Commit Changes to the DataSource ensuring a full transaction, without loss of data.

The other major advantage is that, multiple repository objects will have different instances of dbcontext within them. This can lead to data leaks in complex cases.

Let’s say that you have a requirement to insert a new Developer and a new Project within the same transaction. What happens when the new Developer get’s inserted but the Project Repository fails for some reason. In real-world scenarios, this is quite fatal. We will need to ensure that both the repositories work well, before commiting any change to the database. This is exactly why we decided to not include SaveChanges in any of the repostories. Clear?

Rather, the SaveChanges will be available in the UnitOfWork Class. You will get a better idea once you see the impelemntation.

Let’s get started with the IUnitOfWork. Create a new Interface in the domain Project, Interfaces/IUnitOfWork

public interface IUnitOfWork : IDisposable
{
    IDeveloperRepository Developers { get; }
    IProjectRepository Projects { get; }
    int Complete();
}

You can see that we are listing the interfaces of the required Repositories within the UOW Interface. It’s also a Disposable Element. Finally we have a ‘Complete’ Function which will save the changes to the database.

Let’s implement this interface. Create the implementation at the DataAccess Project. Add a new class in the UnitOfWork/UnitOfWork.cs

public class UnitOfWork : IUnitOfWork
{
    private readonly ApplicationContext _context;
    public UnitOfWork(ApplicationContext context)
    {
        _context = context;
        Developers = new DeveloperRepository(_context);
        Projects = new ProjectRepository(_context);
    }
    public IDeveloperRepository Developers { get; private set; }
    public IProjectRepository Projects { get; private set; }
    public int Complete()
    {
        return _context.SaveChanges();
    }
    public void Dispose()
    {
        _context.Dispose();
    }
}

Note that, Here we are injecting a private AppplicationContext. Let’s wire up or controllers with these Repositories. Ideally you would want to have a service layer between the Repository and Controllers. But, to keep things fairly simple, we will avoid the service layer now.

Before that, let’s not forget to register the IUnitofWork Interface in our Application. Navigate to Startup.cs/ConfigureServices Method and add this line.

services.AddTransient<IUnitOfWork, UnitOfWork>();

Wiring up with an API Controller

Add a new Empty API Controller in the WebAPI Project under the Controllers folder.

[Route("api/[controller]")]
[ApiController]
public class DeveloperController : ControllerBase
{
    private readonly IUnitOfWork _unitOfWork;
    public DeveloperController(IUnitOfWork unitOfWork)
    {
        _unitOfWork = unitOfWork;
    }
}

Here are injecting only the IUnitOfWork object. This way, you can completely avoid writing lines and lines of injections to your controllers.

Now, let’s say we need two endpoints for this controller. A POST and a GET Method.

  • Get all the Popular Developers.
  • Insert a new Develoeper an a new Project.

We’ll start working on the methods now.

public IActionResult GetPopularDevelopers([FromQuery]int count)
{
    var popularDevelopers = _unitOfWork.Developers.GetPopularDevelopers(count);
    return Ok(popularDevelopers);
}

Line #3 – Using the _unitofWork object, we are able to acces the custom method ‘GetPopularDeveloper’ we created. This returns a set of developers sorted by the descending order of the follower count.
Line #4 Returns a 200 Status Ok with the developers.

[HttpPost]
public IActionResult AddDeveloperAndProject()
{
    var developer = new Developer
    {
        Followers = 35,
        Name = "Mukesh Murugan"
    };
    var project = new Project
    {
        Name = "codewithmukesh"
    };
    _unitOfWork.Developers.Add(developer);
    _unitOfWork.Projects.Add(project);
    _unitOfWork.Complete();
    return Ok();

}

Line 4-12 is where I build sample entity objects just for demonstration purpose.
Line 13 – Add the developer object to the uow context.
Line 14 – Add the project object to the uow context.
Line 15 – Finally commits the changes to the database.

What would happen if we didnt have an UnitOfWork Abstraction?

Let’s say Line 13 saves the developer to the database, but for some reason, Line 14 fails to store the project. This can be quite fatal for applications due to data inconsistency. By introducing a unit of work, we are able to store both the developer and project in one go, in a single transaction.

Testing with PostMan

Adding a new Developer and Project. Open up Postman and send a POST request to https://localhost:xxxx/api/developer

post

We get a 200 Ok Status Code, which means that the unit of work trasaction is completed. Now let’s fetch the data and check.

get

As expected, we are able to retreive the inserted data. That’s it for this extensive guide on Repository Pattern in ASP.NET Core Applications or C# in general.

If you found this article helpful, consider supporting.

Buy me a coffeeBuy me a coffee

Summary

We learnt all about Repository Pattern in ASP.NET Core Application, Generic Repositories, Unit Of Work , a cleaner way to access data with layered projects, and other Use Case Scenarios. This covers nearly everything that you would need to know to become a Pro at Repository Pattern in ASP.NET Core. Have any suggestions or question? Feel free to leave them in the comments section below. Here is the source code of the implementation for your reference. Thanks and Happy Coding! πŸ˜€

32 Comments

  1. Arjunan

    Perfect one… Thanks for sharing detailed article.

    Reply
    • Mukesh Murugan

      Thanks! Hope you are liking the blog posts πŸ˜€
      Regards

      Reply
  2. Victor

    Great Article. Quick question, can the repository pattern above be implemented with the CQRS pattern?
    How would that work? Awesome job as always.

    Reply
    • Mukesh Murugan

      It really “depends”. If you are building a small application, NO. If you are a building an Enterprise level application with like 10K Lines of code, you would benefit by deceoupling the dbContext away from the Application layer. The only problem that i see is that you would end up with on additional layer of arbitration. But if you want to keep your code organized and much testable, Repository is the way to go. I have seen a couple of Projects over at GitHub implementing both Repository Pattern and CQRS. It’s used, but not widely.

      Reply
    • Mukesh Murugan

      Hi again, Have a look at https://github.com/dotnet-architecture/eShopOnWeb . This is one of repositories maintained by Microsoft themselves. You can see at https://github.com/dotnet-architecture/eShopOnWeb/blob/master/src/Web/Features/MyOrders/GetMyOrdersHandler.cs that they themselves are using Repository Pattern along with CQRS. Summary is that, if you think it is maintainable and easy to understand for you, then Repository + CQRS is also a way to go about it.

      Thanks and Regards

      Reply
  3. Gaurav Vashisth

    Hey , I am just a beginner in .net and c# . And I want to know about the job opportunities in c# .net in India .
    I am in final year of my graduation which is done now and I want to get a job and basically I am from a bit of java background like core Java and few days back a got an internship where i work on Microsoft dynamics 365 technology and where i have to work on JavaScript and C sharp . So please tell me what I do further

    Reply
  4. Rasmus Schultz

    Please read this article:

    https://altkomsoftware.pl/en/blog/create-better-code-using-domain-driven-design/

    “In domain driven design a repository is not just a data access object, which implements all CRUD and database queries needed for given entity type. In domain driven design repository should be part of the ubiquitous language and should reflect business concepts. This means that methods on repository should follow our domain language not the database concepts.
    We often see generic repositories with methods for CRUD and methods allowing execution of ad-hoc queries. This is not a good way if we want to follow DDD principles.
    Instead we should only expose operations required and create methods for queries related to business concepts.”

    What you’ve built here is more like a “document database” and your entities more like “mutable documents” than entities.

    Don’t feel bad though. Everyone gets this wrong at first, and all the popular articles on the subject teach it this way. Once you’ve tried repositories the DDD way, you’ll see the benefits. πŸ™‚

    Reply
    • macoratti

      I’m new developer and I’ve read a lot about repository and DDD,
      and it seems that DDD is only recommended to large enterprise applications.

      In small and medium applications can still I use instead repository pattern as β€œdocument database” ?

      Reply
      • Mukesh Murugan

        Usage of design patterns solely depends on the developer. If you are comfortable and think that Repository pattern makes sense, go ahead with it. This patterns helps make your application more decoupled.

        Thanks and Regards

        Reply
  5. Samuel Iyomere

    Thank you for this article.

    I’ve been using repository pattern since MVC4 but haven’t used GenericRepository and UnitOfWork. I just started a new project using .NETCore Api and MongoClient for MongoDb. I will try using this approach and if it works then this will become my new design pattern.

    Thanks Mukesh.

    Reply
    • Mukesh Murugan

      Hi, It’s quite a brilliant pattern if used wisely. Keep me posted about your project.
      Thanks and Regards.

      Reply
  6. John McHale

    What about using a generic UnitOfWork Pattern. Otherwise, any time you want to add a new repository (e.g. ManagersRepository, TasksRepository) you will have to change your IUnitOFWork interface as well as the concrete UnitOfWork class

    Reply
  7. Jugan

    How would be the idea of implementing repository patter with onion architecture? Can you please direct me with some articles?

    Reply
      • Jugan

        Thanks, Mukesh. I am working on learning new architectures and patterns (I have developed all my projects with only N-layer). I view your blog will be a lead to it. I will go through the repository for better knowledge.

        Reply
        • Jugan

          Hi Mukesh, I was going through your GitHub repo on CleanArchitecture. It has served me to acquire knowledge about architecture in detail. I would wish to know if the UOW layer is not required/possible or have you proposed to integrate in the future.

          Thanks in advance

          Reply
          • Mukesh Murugan

            Hi Jugan,
            Yes, since the Repository pattern implementation depends on the develops choice, it can still be clean with a UOW Layer. But to have a much better separation, UOW is a must. I am still in process of building the API. (Currently working on the Auth Services). I will be adding the UOW as well in a few days. However I guess you can get a good overview of clean architecture via the github repo already. Do share it within your community.

            Thanks and Regards.

  8. Vinod Kumar Gupta

    Nice article Mukesh, appreciated

    Reply
  9. Dota

    Great article! Good job on it, I’ve learned quite a lot. I just have a question.
    Is there any particular reason to keep the repositories registered once you implemented the unit of work?

    Can we have
    services.AddTransient();

    Instead of
    services.AddTransient(typeof(IGenericRepository), typeof(GenericRepository));
    services.AddTransient();
    services.AddTransient();

    If not, what is the reason to keep the repositories? Thanks in advance and keep up the great work!

    Reply
    • Mukesh Murugan

      Hey, Thanks for the feedback.

      Yes, Thanks for pointing out that to me. You really don’t need to Register the IRepos and UOW takes care of all that. You will just need a services.AddTransient(); in your startup. That’s all you would need. I guess I have left out some residue code.

      Thanks and Regards

      Reply
  10. Praful Kumar

    Very much appreciated…

    Reply
  11. John Doe

    Good article. However, may I suggest a few improvements:
    1. Do not return IEnumerable but instead use IQueryable. With the IEnumerable, you are forcing the queries to load the whole data in the table in memory. This is not only slow but may also crash your server if you have large tables with limited RAM. The IQueryable would allow you to improve the performance.
    2. You do not need the unit of work pattern. EF Core already implements it. See this post (https://www.programmingwithwolfgang.com/repository-pattern-net-core/) for better generic repository implementations.

    Either way, thanks for your detailed explanations.

    Reply
  12. Rahul

    Hey, nice article only question is how you will implement an identity framework in this pattern I mean in which layer? I have read many articles in which the user manager and sign in manager are used within the controller itself which means giving the database calls from the controller. Any idea or article on this will help thanks.

    Reply
    • Mukesh Murugan

      Hi, I would not put them within the controller. If I was using an Onion Architecture, I would add an IAccountService, that has AuthenticateAsync, RegisterAsync and so on. Then I would create a new Infrastructure Layer, Infrastructure.Identity and implement IAccountService in this layer. I dont have an article regarding the same, but you can check my Clean Architecture in WebApi Repository – https://github.com/iammukeshm/CleanArchitecture.WebApi . The same concept is implemented here.

      Thanks and Regards

      Reply
      • Rahul

        Thanks, for the reply I will try to implement as suggested above.

        Reply
  13. idchlife

    Hi! Thanks for the article! It’s very nice!

    Several years ago I was developing with Symfony 2 framework. Doctrine is used as ORM with unit of work and repositories there.

    The thing is, one of the practices there was: create service, which inherits from default entity repository (with all common methods, findById, find, findAll etc). So instead of getting generic repository we were able to get generic repository as service + our additional methods in this service. Basically a win-win situation. We had full first-level access to all the default methods of repositories with our additional methods like “findByEmail” or “findByRelationshipId” etc.

    You can see example of such thing here: https://tomasvotruba.com/blog/2017/10/16/how-to-use-repository-with-doctrine-as-service-in-symfony/

    When I started using AspNet with Entity Framework Core, I was surprised that I did not witness word “Repository” anywhere.
    Some time passed and I discovered that actually EF Core introduced unit of work and repositores as db context, and apparently Entity Framework did not have those inside.

    Is it possible in AspNet + Ef Core to code like it is possible in Symfony + Doctrine? To create separate repositories of entities which wll inherit all default DbSet methods etc? Maybe it is the way, to create custom class which would extend DbSet and register it inside DbContext?

    Reply
  14. Lokendra Chand

    Hi, Mukesh sir,

    I understood this . But could you please let me know how to use Unit of Work in Two tables when we need to join table. Furthermore, how to setup generic repository for multiple table query

    Reply
  15. Sreenath Ganga

    Hi Mukesh
    Well explained and simply explained. Very good for those who likes to use this pattern without diving deep to the theory of patterns and what each part does, All blogs are super
    Hope we can meet some time in TVM

    Reply
  16. Saif

    Hi Mukesh,
    Great article. But what will be the problem if we refactor the GenericRepository as like

    public interface IGenericRepository where T : class
    {
    Task GetByIdAsync (int id);
    Task<IEnumerable> GetAllAsync ();
    Task<IEnumerable> FindAsync (Expression<Func> expression);
    Task AddAsync (T entity);
    Task AddRangeAsync (IEnumerable entities);
    Task RemoveAsync (T entity);
    Task RemoveRangeAsync (IEnumerable entities);
    }

    Reply

Submit a Comment

Your email address will not be published. Required fields are marked *

Follow codewithmukesh

Support Me!

Buy me a coffeeBuy me a coffee

Pin It on Pinterest