How To Create Industry Standard .NET Core CRUD API Quickly

Overview

Practically speaking, designing CRUD-based applications is similar in all products. But still, we need to write the same code from scratch. Also, for CRUD applications, the most preferable pattern is the Repository pattern. However, it would be good if we have a generic tool that should follow the SOLID rules and is comfortable to use with all CRUD-related products. In this article, we are going to use the same repository pattern implemented with the NuGet package RS2.Core.

So, in this article, we are going to

  • create a business logic
  • create a Web API project
  • add a model class and database context.
  • register dependencies

Prerequisites

Creating Business Logic

Select the Add -> New Project menu option. On the "New Project" dialog, select .NET Core from the left side and select Class Library (.NET Core) template on the right side.

 Business Logic

Give your project a name, select a folder where you want your project to be created, and click OK. This will create your first .NET Core Class Library project. I gave my project the name “BusinessLogic”.

Right-click the solution and select "Manage NuGet Packages for Solution".

Manage NuGet

Select the "Browse" tab and search for RS2.Core.

Browse

Mark the BusinessLogic project on the right side and click "Install". Press "I Accept" on the license appliance.

Add three different folders for Entities, Logics, and Context respectively under the BusinessLogic project.

Create Entities

Entities should be inherited from the Core Library which contains the required properties. For example -the ID field (generic type), IsActive. EntityBase is the base class for master entities and EntityTranBase is for transaction entities, which contains the create and update properties. Let's create the Category and Product entities for now.

Category

  • Rename the "Class1" on Solution Explorer as "Category".
  • Move it to the "Entities" folder.
  • Replace with the below code.
    using System;
    using RS2.Core;
    
    namespace BusinessLogic {
        public class Category : EntityBase<int> {
            public string CategoryName { get; set; }
            public string ImageURL { get; set; }
        }
    }
    

Product

  • Right-click the "Entities" folder.
  • Select Add > Class.
  • Name the class Product, and select "Add".
  • Replace with the below code
    using System;
    using System.Collections.Generic;
    using RS2.Core;
    
    namespace BusinessLogic {
        public class Product : EntityBase<long> {
            public string ProductName { get; set; }
            public decimal Price { get; set; }
            public int CategoryId { get; set; }
            public virtual Category Category { get; set; }
        }
    }
    

Create DB Context

For the Code-First approach, we just create a context class and create DbSet objects for each entity. Let's create them for Product and Category Entities.

  • Right-click the "Context" folder
  • Select Add > Class.
  • Name the class as ShoppingContext, select "Add".
  • Replace with the below code.
    using Microsoft.EntityFrameworkCore;
    
    namespace BusinessLogic
    {
        public class ShoppingContext : DbContext
        {
            public ShoppingContext(DbContextOptions<ShoppingContext> options) : base(options)
            {
                Database.EnsureCreated();
            }
    
            public DbSet<Category> Categories { get; set; }
            public DbSet<Product> Products { get; set; }
        }
    }
    

Create Business Logic classes

Creating business logic with the RS2.The core library is very simple. We need to create an interface for each entity and inherit the interface from IRepositoryBase for CRUD-required entities or IGetRepository for read-only entities (Ex: Country, this object does not require an add or edit screen). Now, the Business class should be inherited from the interface created from the RepositoryBase class from Core Library and the interface we have created for the entity. Let's create the same for the Product and Category entities.

Category Repository

  • Right-click the Logics folder.
  • Select Add > Class
  • Name the class CategoryRepository
  • Select "Add"
  • Replace with the below code.
    using RS2.Core;
    
    namespace BusinessLogic {
        public interface ICategoryRepository : IRepositoryBase<Category, int> {}
        
        public class CategoryRepository : RepositoryBase<Category, int>, ICategoryRepository {
            public CategoryRepository(IUnitOfWork unitOfWork) : base(unitOfWork) {}
        }
    }
    

Product Repository

  • Right-click the Logics folder.
  • Select Add > Class.
  • Name the class ProductRepository.
  • Select "Add".
  • Replace with the below code.
    using RS2.Core;
    using Microsoft.EntityFrameworkCore;
    
    namespace BusinessLogic {
        public interface IProductRepository : IRepositoryBase<Product, long> {}
        
        public class ProductRepository : RepositoryBase<Product, long>, IProductRepository {
            public ProductRepository(IUnitOfWork unitOfWork) : base(unitOfWork) {}
    
            protected override IQueryable<Product> GetAllAsyncQuery(bool excludeDeleted = true) {
                return Entity.Include(e => e.Category).Where(p => !excludeDeleted || p.IsActive);
            }
        }
    }
    

Creating API

Now, let's create a Web API project and create the ASPI for both Category and Product entities. Add a new project with the below steps.

  • Right-click the solution.
  • Select Add > New Project.
  • Select Web > ASP.NET Core Web Applications.
  • Name the project as API, and select OK.
  • Now, select the API template and press OK.
  • Right-click solution.
  • Select "Manage NuGet Packages for Solution".
  • Choose the Installed tab and select RS2.Core.
  • Mark Api project at the right side window and click install.
  • Accept the license for installation to complete.
    Creating API

Adding a Business Logic project reference to the API project

To use business entities and logic in the API project, we are adding the BusinessLogic project reference to the API project using the below steps.

  • Right-click on the dependencies of the API project
  • Select "Add Reference".
  • Select the Projects tab on the left side.
  • Mark the BusinessLogic from the list and press OK.

Now, create the API controllers for Category and Product by the below-given steps.

Category Controller

  • Right-click the Controllers folder.
  • Select Add > Controller, and select the API Controller - Empty template.
  • In the "Add New Item" dialog, name the class CategoriesController, and select Add.

Let's call the CRUD operations from business logic. The below code will explain how to call business logic from our API for the Category entity.

using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using RS2.Core;
using BusinessLogic;

namespace Api.Controllers
{
    [Produces("application/json")]
    [Route("api/[controller]")]
    [ApiController]
    public class CategoriesController : ControllerBase
    {
        private ICategoryRepository _categoryRepository;
        private IUnitOfWork _unitOfWork;

        public CategoriesController(ICategoryRepository categoryRepository, IUnitOfWork unitOfWork)
        {
            _categoryRepository = categoryRepository;
            _unitOfWork = unitOfWork;
        }

        // GET: api/Categories
        [HttpGet]
        public async Task<IEnumerable<Category>> Get()
        {
            return await _categoryRepository.GetAllAsync();
        }

        // GET: api/Categories/5
        [HttpGet("{id}")]
        public async Task<Category> Get(int id)
        {
            return await _categoryRepository.GetAsync(id);
        }

        // POST: api/Categories 
        [HttpPost]
        public async Task Post([FromBody] Category category)
        {
            await _categoryRepository.SaveAsync(category);
            // Commit the changes.
            await _unitOfWork.CommitAsync();
        }

        // DELETE: api/ApiWithActions/5
        [HttpDelete("{id}")]
        public async Task Delete(int id)
        {
            await _categoryRepository.SoftDelete(id); // Set Deleted flag.
            //await _categoryRepository.HardDelete(id); // Delete from DB
            // Commit the changes.
            await _unitOfWork.CommitAsync();
        }
    }
}

Products Controller

  • Right-click the Controllers folder.
  • Select Add > Controller, and select the API Controller - Empty template.
  • In the "Add New Item" dialog, name the class asProductsController, and select Add.

The below code will explain how to call the API methods from business logic for the product entity.

using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using RS2.Core;
using BusinessLogic;

namespace Api.Controllers
{
    [Produces("application/json")]
    [Route("api/[controller]")]
    [ApiController]
    public class ProductsController : ControllerBase
    {
        private IProductRepository _productRepository;
        private IUnitOfWork _unitOfWork;

        public ProductsController(IProductRepository productRepository, IUnitOfWork unitOfWork)
        {
            _productRepository = productRepository;
            _unitOfWork = unitOfWork;
        }

        // GET: api/Products
        [HttpGet]
        public async Task<IEnumerable<Product>> Get()
        {
            return await _productRepository.GetAllAsync();
        }

        // GET: api/Products/5
        [HttpGet("{id}")]
        public async Task<Product> Get(int id)
        {
            return await _productRepository.GetAsync(id);
        }

        // POST: api/Products
        [HttpPost]
        public async Task Post([FromBody] Product product)
        {
            await _productRepository.SaveAsync(product);
            // Commit the changes.
            await _unitOfWork.CommitAsync();
        }

        // DELETE: api/ApiWithActions/5
        [HttpDelete("{id}")]
        public async Task Delete(int id)
        {
            await _productRepository.SoftDelete(id); // Set Deleted flag.
            //await _productRepository.HardDelete(id); // Delete from DB
            // Commit the changes.
            await _unitOfWork.CommitAsync();
        }
    }
}

Register the dependencies

Now, we need to register the dependencies, i.e., in the above controller code, we are just injecting the appropriate interface and calling the methods. So, we are configuring the dependency to that interface saying this interface contains the object for this class. For example, if we use IProductRepository, that should hold the object of the ProductRepository class. These dependencies we are injecting at StartUp.cs. The below code will explain how to configure a dependency in StartUp.cs.

public void ConfigureServices(IServiceCollection services)
{
    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
    services.AddDbContext<ShoppingContext>(options => options.UseSqlServer(Configuration.GetConnectionString("ShoppingConnection")));
    services.AddScoped<DbContext, ShoppingContext>();
    services.AddScoped<IUnitOfWork, UnitOfWork>();
    services.AddScoped<ICategoryRepository, CategoryRepository>();
    services.AddScoped<IProductRepository, ProductRepository>();
}

We are done with the ApI creation. Below is an example of calling the API. Make sure you have configured the connection string properly in the appsettings.json file.

  • https://localhost:8080/api/products/2
  • https://localhost:8080/api/categories