Blog

You are here: Blog / Develop Microservice using Asp.net core and Docker

  • Microservices Architecture

    Develop Microservice using ASP.NET Core and Docker

    Microservices can be deployed independent service and can be accessible separately for each domain base on business requirement. Also we can implement each service on different technology stack if required.

    Microservices is more about applying a specific number of standards and designs as engineering. Every microservice lives freely, however then again, likewise all depend on one another.

    All microservices in a task get conveyed underway at their own speed, on premise on the cloud, autonomously, living next to each other. In this instructional exercise, figure out how to assemble a microservice utilizing ASP.NET and build, deploy and test it using a docker holder.


    Benefits of Microservices:

    • Enable CI/CD approach which help in developing large and complex application.
    • As each services are relatively small so it is easy to understand, Improved maintainability and easy to change.
    • Easy to test as services are smaller and faster to test and easy to find issue.
    • Better deployment - services can be deployed independently.
    • As each service are behave independently, So development effort can be organize with multiple team and do faster development parallel. Each service responsible team can develop, test, deploy and scale their services independently without causing any issue to other team members or team.
    • Each microservice is relatively small.
    • Easier for a developer to understand.
    • The IDE is making developers more productive and faster.

    Let’s simplify microservices architecture as per above image.

    1. Clients:

    Here Clients means any Frontend application which can be access the API to connect with backend.

    2. API Gateway:

    For the security reason clients do not call the service directly added API gateway layer which acts as entry point for the clients to send requests to appropriate microservices.

    3. Microservice Layer:

    This layer contains multiple services and can be deploy in different server base on the technology stack the service has been develop.

    Docker Containers

    Docker containers are designed to run on everything, from physical computers to virtual machines, bare-metal servers, OpenStack cloud clusters, public instances and lots of more. Docker extends the Linux Containers (LXC) format, which serves to supply an isolated environment for applications, by enabling image management and deployment services.


    HOW TO DEVELOP MICROSERVICES USING .NET CORE

    Step 1: Open the Visual Studio, click on add a new project.

    Step 2: Pick the application as ASP.NET Core Web Application and give it an important name.


    Step 3: Then, pick API as the sort of the Project and ensure that the "Enable Docker Support" alternative is chosen with OS type as Linux.

    Step 4: The solution will look as shown below.

    Step 5: Add a new folder named “Model” to the project.

    Step 6: In the Models folder, add a class named Service.

    Step 7: Add a few properties like Id, Name, Description, Price to the Service class. The Service should be kind and for that, a category model is defined, and CategoryId property is added to the Service model.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace MicroServices.Models
    {
        public class Service
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public decimal Price { get; set; }
            public int CategoryId { get; set; }
        }
    }
    

    Step 8: Essentially, add a Category model

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    
    namespace MicroServices.Models
    {
        public class Category
        {
            public int Id { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
        }
    }

    Step 9: Enabling EF Core

    However, the .NET Core API project has inbuilt help for EF Core and all the connected dependencies are downloaded at the time of project creation and compilation that could be found under the Packages area in the project as shown below.

    Microsoft.EntityFrameworkCore.SqlServer should be the package inside the downloaded packages. If not present, it should be explicitly added to the project through Nuget Packages.

    Step 10: Add another folder named DBContexts to the solution

    Step 11:

    Add another class named ServiceContext which includes the DbSet properties for Services and Categories. OnModelCreating is a strategy via the master data that could be cultivated to the database. Thus, add the OnModelCreating technique and add categories that will be added to the database at first into the category table when the database is created

     using Microsoft.EntityFrameworkCore;
    using MicroServices.Models;
    
    namespace MicroServices.DBContexts
    {
        public class ServiceContext : DbContext
        {
            public ServiceContext(DbContextOptions options) : base(options)
            {
            }
            public DbSet Services { get; set; }
            public DbSet Categories { get; set; }
    
            protected override void OnModelCreating(ModelBuilder modelBuilder)
            {
                modelBuilder.Entity().HasData(
                    new Category
                    {
                        Id = 1,
                        Name = "Electronics",
                        Description = "Electronic Items",
                    },
                    new Category
                    {
                        Id = 2,
                        Name = "Clothes",
                        Description = "Dresses",
                    },
                    new Category
                    {
                        Id = 3,
                        Name = "Grocery",
                        Description = "Grocery Items",
                    }
                );
            }
    
        }
    }
    

    Step 12:

    Add a new folder named Repository in the project and add an Interface name IServiceRepository in that folder. Add methods in interface which performs CRUD operations for service microservice

    using MicroServices.Models;
    using System.Collections.Generic;
    
    namespace Microservice.Repository
    {
          public interface IServiceRepository
          {
                IEnumerable GetServices();
                Service GetServiceByID(int service);
                void InsertService(Service service);
                void DeleteService(int serviceId);
                void UpdateService(Service service);
                void Save();
          }
    }

    Step 13:

    Add a new concrete class named Service Repository in the same Repository folder that implements IService Repository. All these methods need:

     using Microsoft.EntityFrameworkCore;
    using Microservice.Repository;
    using MicroServices.DBContexts;
    using MicroServices.Models;
    using System;
    using System.Collections.Generic;
    using System.Linq;
    
    namespace Microservice.Repository
    {
      public class ServiceRepository : IServiceRepository
      {
        private readonly ServiceContext _dbContext;
    
        public ServiceRepository(ServiceContext dbContext)
        {
          _dbContext = dbContext;
        }
        public void DeleteService(int ServiceId)
        {
          var Service = _dbContext.Services.Find(ServiceId);
          _dbContext.Services.Remove(Service);
          Save();
        }
    
        public Service GetServiceByID(int ServiceId)
        {
          return _dbContext.Services.Find(ServiceId);
        }
    
        public IEnumerable GetServices()
        {
          return _dbContext.Services.ToList();
        }
    
        public void InsertService(Service Service)
        {
          _dbContext.Add(Service);
          Save();    }
    
        public void Save()
        {
          _dbContext.SaveChanges();
        }
    
        public void UpdateService(Service Service)
        {
          _dbContext.Entry(Service).State = EntityState.Modified;
          Save();
        }
      }
    }
    

    Step 14: Add connection string in appSettings.Json file.

    {
      "Logging": {
        "LogLevel": {
          "Default": "Warning"
        }
      },
      "AllowedHosts": "*",
      "ConnectionStrings": {
        "ServicetDB": "Data Source=10.0.75.1,1433;Database=ServiceDB;User ID=sa;Password=sqlserver123;MultipleActiveResultSets=true;"
      }
    }
    

    Step 15: Add code in Startup class in the project and add the code as services. AddTransient(); inside ConfigureServices method so that the repository’s dependency is resolved at a run time when needed.

    public void ConfigureServices(IServiceCollection services)
            {
                services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
                services.AddDbContext(o => o.UseSqlServer(Configuration.GetConnectionString("ServiceDB")));
                services.AddTransient();
            }
    

    Step 16: Add new controller file under the controllers folder into the solution.


    Step 17: Now name controller as ServiceController.

    Step 18: Now add code in ServiceController.

    using System.Transactions;
    using Microsoft.AspNetCore.Mvc;
    using MicroServices.Models;
    using MicroServices.Repository;
    
    namespace MicroServices.Controllers
    {
        [Route("api/[controller]")]
        [ApiController]
        public class ServiceController : ControllerBase
        {
            private readonly IServiceRepository _serviceRepository;
            public ServiceController(IServiceRepository serviceRepository)
            {
                _serviceRepository = serviceRepository;
            }
            // GET: api/service
            [HttpGet]
            public IActionResult Get()
            {
                var services = _serviceRepository.GetServices();
                return new OkObjectResult(services);
            }
            // GET: api/service/5
            [HttpGet("{id}", Name = "Get")]
            public IActionResult Get(int id)
            {
                var service = _serviceRepository.GetServiceByID(id);
                return new OkObjectResult(service);
            }
            // POST: api/service
            [HttpPost]
            public IActionResult Post([FromBody] Service service)
            {
                using (var scope = new TransactionScope())
                {
                    _serviceRepository.InsertService(service);
                    scope.Complete();
                    return CreatedAtAction(nameof(Get), new { id = service.Id }, service);
                }
            }
            // PUT: api/service/5
            [HttpPut]
            public IActionResult Put([FromBody] Service service)
            {
                if (service != null)
                {
                    using (var scope = new TransactionScope())
                    {
                        _serviceRepository.UpdateService(service);
                        scope.Complete();
                        return new OkResult();
                    }
                }
                return new NoContentResult();
            }
            // DELETE: api/ApiWithActions/5
            [HttpDelete("{id}")]
            public IActionResult Delete(int id)
            {
                _serviceRepository.DeleteService(id);
                return new OkResult();
            }
        }
    }
    


    Enable the core migration

    Migrations allow to provide code to change the database from one version to another

    Step 1: Open Package Manager Console.

    Step 2: To enable the migration, type the command, Add-Migration and give that a meaningful name for e.g. serviceCreate and press enter.

    Step 3: After enable migration update your database by command update-database and check for created database in SQL server.

    Database will looks as below


    Run The Microservice Via IIS Express

    Please select IIS Express in the Visual Studio as shown below, press F5 or click IIS Express button.

    Postman

    We use postman for api call, which can Make any kind of API call—REST, SOAP/plain HTTP and easily inspect even with the largest responses. Postman has builtin support for popular data formats such as OpenAPI, GraphQL and RAML.

    Now for adding records in database table we need to call POST method; i.e. create a new resource, select method as POST in postman and then provide the endpoint, i.e. http://localhost:44312/api/service and in the Body section, add a JSON similar to having properties of Service model as shown below and click on Send.

    Select content type as JSON. sample data for adding record as below

    {
       "Name":"Tom",
       "Description":"Test1",
       "Price":60000,
       "CategoryId":1
    }

    Now select records in sql server using select statement for Services table.

    Perform a GET request now with the same address and get added record as a JSON format response

    For delete record from database we need to call delete request by selecting DELETE as the verb and appending id as 1 (if the service with id 1 needs to be deleted) and press Send

    Now for delete record with ID - 3 we need to call delete method using postman. Execute api with url http://localhost:44312/api/service/3

    Getting records looks like below.


    Run The Microservice Via Docker Container

    Now running the service could be done via docker commands to be run in docker command prompt and using visual studio as well. we added the docker support, easy to run service in docker container using visual studio

    Step 1: Add container orchestrator support in the solution and Select Docker Compose and press OK.

    Step 2: Run project now with docker compose.

    Step 3: Now open command prompt and select directory of project where docker files are located and execute command:- docker images and press enter.

    Step 4: Now, run the command docker ps to see the running containers. It shows the container is running on 49153:80 port.


    Conclusion:

    Basically microservices are an style of architecture that develops one application as a group of small services. Each service runs in its own process. The services communicate with clients and sometimes one another , using lightweight protocols, often over messaging or HTTP.

    More angular topic: