Friday, July 7, 2017

Create Your Rest/Web API Architecture with ASP .Net Core 1.1 from Scratch




Today I came up with Web API solution with .Net Core 1.1 from scratch, in this Article/POC we will focus more on architectural pattern of the solution means how to organise your solution architecture of the Web API with different layer, I try to follow some of the key design principles/Architecture Pattern/technology as below

  • Separate of concern
  • Repository pattern
  • Dependency Injection Containers (IOC)
  • N-Tier Project Architecture
  • Entity Framework Core
  • .Net Core Web API




Below is the high-level architecture and data flow diagram of Web API.




I am going to use Visual Studio 2017 RC and IDE, but you can also use Visual Studio 2015 as IDE. If you don’t have the template for ASP.NET Core, you need to install this template
Let’s take an example of ABCSoftware Company which need to expose the API to provides the related software Product information like ProductName, Price, details etc.

   
I quickly created sample database and table using below script

create database ABCSoftware
use ABCSoftware


CREATE TABLE PRODUCT(PRODUCTID INTEGER NOT NULL PRIMARY KEY,CODE VARCHAR(5),NAME VARCHAR(100),UNITPRICE NUMERIC(6,2) NOT NULL);


INSERT INTO PRODUCT VALUES(10,'AB123','ORACLE',1000);
INSERT INTO PRODUCT VALUES(20,'AB456','E-commerce',200.25);
INSERT INTO PRODUCT VALUES(30,'AB789','Online marketing',250.60);
INSERT INTO PRODUCT VALUES(40,'PQ123','School management',399);
INSERT INTO PRODUCT VALUES(50,'PQ456','OfficeManagement Software',1050);
INSERT INTO PRODUCT VALUES(60,'PQ789','Inventory Management Softare',2250.99);






Create Visual Studio Project using .NetCore Web API

Open VS2017 > create .Net core Web Application using (.NetCore),
 NOTE: we can either create a .NET Core Web Application which targets .NET Core or a .NET Core Web Application which targets the full .Net Framework.
If you target .NET Core, then you can run the app anywhere that supports .NET Core (Linux, Mac, and Windows).
You will also have to stick to third party libraries that support Core and you won’t be able to use some stuff that exists in the full framework and hasn’t been included in Core.
Alternatively, you can target the full .Net Framework. You’ll be limited to Windows (for hosting) but can use any third party library and everything that exists in the framework.
So I am creating .NET Core Web Application which targets .NETCore




Then select the webAPI template using ASP.NET Core 1.1  as below



Rename the Project name from ABCSoftware to ABCSoftware.API as below



Add the Different  Project Layer in the solution
Go to the solution > Add the New Project > Class Library(.Net Core)



We need to create the below Project layers ( .NetCore Class Library projects) in the solution with above steps:

ABCSoftware.Data: This is Data layer which is responsible for all database related tasks. The purpose of this layer is the direct access to the database. It’s the only layer responsible for communicating with the database. If some other layer wants to access the database, then this will be done through some of the classes (repositories) we will define in this project. Also, we will create the Repository/ DBContext in this layer only.

ABCSoftware.Model: We will keep all of our domain objects in this library.

ABCSoftware.Service: This Layer is responsible for all the operation that need to expose in the MVC controller, all the Business Logic will go in this layer. This layer will directly be communicated to the Controller.

ABCSoftware.Configuration: This library is where we will keep all the configuration and the settings of the project.

After adding all the above the above library in the solution, our project will look like below:



ADD Model in the ABCSoftware.Model Project

Add a new class in the ABCSoftware.Model project named Product as below:



class Product
    {
        [Key]
        public int PRODUCTID { get; set; }
        public string CODE { get; set; }
        public string NAME { get; set; }
        public decimal UNITPRICE { get; set; }
    }


Preparing DATA layer

Adding connection string and setting up DbContext
Got to ABCSoftware.API project > appsetting.json and add the connection string named DBConnection here as below:





Now, Let's add base context class which will inherit from DbContext class
Go to the DemoSoftware.Data project > Add one class called DatabaseContext as below:



Oops, DbContext is not resolved, Yes, Now Time to install Entity Framework.

ADD Entity Framework Core reference from Nuget in Data Library Project.
To install the package, just right click on the project ABCSoftware.Data and then, select "Manage NuGet package". The below dialog of Nuget Package Manager will pop up. In the Browse tab, there is a search box. Type “Microsoft.EntityFrameworkCore.SqlServer” and just click on "Install" button to install.

Note: make sure you select latest stable version, 1.1.2 is currently compatible with ASP.NET core 1.1



Now check the DatabaseContext Class, and resolve the DbContext with using Microsoft.EntityFrameworkCore;





Add the below code in the DatabaseContext Class

public class DatabaseContext : DbContext
    {
        public DatabaseContext(DbContextOptions<DatabaseContext> options) : base(options)
        {

        }

        public DbSet<Product> Product { get; set; }
    }


           
Adding Repositories in The Data Layer

Create one Folder in the DemoSoftware.Data project called Repositories
Add one class in the Repositories folder called ProductRespository and one interface called IProductRespository in the Repositories folder by Right click > Add > New item > Class




Go to ABCSoftware.Data project >  Add the project reference of ABCSoftware.Model



Go to IProductRepository Interface and add the below code
List<Product> GetProductList();

Go to ProductRepository implementation class and add the below code:
class ProductRepository : IProductRepository
    {

        private DatabaseContext _DbContext;

        public ProductRepository(DatabaseContext Dbcontext)
        {
            _DbContext = Dbcontext;
        }
        public IEnumerable<Product> GetProductList()
        {
           return _DbContext.Product;
        }
    }





Now our data layer is completed, repositories have been created, let's create the service layer.

ADD Service layer

Go to the ABCSoftware.Service Project and Add Folder Called Services > Under this folder create one class called ProductService and IProductService Interface as below:



Add data and Model project reference in the service project as below:



Add the below code in the IProductService Interface as below:

   public  interface IProductService
    {
        IEnumerable<Product> GetAllProduct();
    }

And add the below code in the ProductService implementation class:
class ProductService : IProductService
    {
        private IProductRepository _productRepository;

        public ProductService(IProductRepository productRepository)
        {
            _productRepository = productRepository;
        }
        public IEnumerable<Product> GetAllProduct()
        {
            return _productRepository.GetProductList();
        }
    }



This Service layer will call the repository class in the data layer as the above code.

And IproductService exposed only one method called GetAllProduct() and will call by controller class.

ADD Controller method
Now go to the web project >  Right Click > and add one controller class called ProductController:









Add Minimal Dependency
Add API Controller:








Go to Productcontoller > and Add the below Code:
public class ProductController : Controller
    {


        private IProductService _productService;

        public ProductController(IProductService productService)
        {
            _productService = productService;
        }

        [HttpGet]
        public IEnumerable<Product> GetProductData()
        {
            return _productService.GetAllProduct();
        }
    }



Now, everything is done!! Let’s Execute the API to test..
OOPS, we didn’t resolve the Repository and service layer dependency, let's resolve this first:

Add Dependency Injection in the Solution

Go to ABCSoftware.Configuration Project > Add one class file called DependencyResolver

Add Microsoft.EntityFrameworkCore.SqlServer reference in the Project
Add Service and Repository Project reference in the Project



Below is the code of the class

public static class DependencyResolver
    {
       
        public static void RegisterDependency(IServiceCollection _ServiceCollection,string connectionString)
        {
            //adding DB Dependecy Injection
            _ServiceCollection.AddDbContext<DatabaseContext>(options => options.UseSqlServer(connectionString));

            //Adding repository DI
            _ServiceCollection.AddTransient<IProductRepository, ProductRepository>();

            //Adding Service DI
            _ServiceCollection.AddTransient<IProductService, ProductService>();
        }
    }



Now go to ABCSoftware.API Project > Add Project Reference > ABCSoftware.Configuration

Go to the Startup.cs class and add the below code in the ConfigureServices() Method
      var con = Configuration.GetConnectionString("DBConnection");
            DependencyResolver.RegisterDependency(services,con);





Now all dependency will resolve through the common function called  RegisterDependency from DependencyResolver Class, This is a Just example of SOC(Separation of Concern) and also no need to get reference of Data Project directly in the ABCSoftware.API Project.

Now Build the solution and Run the Site using local IIS Express( using F5)
Check the result localhost/api/Product
If you want to host this API on Windows Server IIS, follow the below link



Testing ASP.net core Web API (HTTP request) Using Postman.
Download the POSTMAN APP, https//www.getpostman.com/ 
After download and install the Postman, Just check the HTTP Request as below:



I hope this article will help you to understand the Web API concepts using .Net Core.
If you have any questions or concerns, please get in touch with me on Twitter @sitecore_ashish or on Slack).