
In today's software world, applications are no longer built as one big block (monolith) where everything - UI, logic, and database - is tightly connected. Instead, developers use Microservices Architecture, where an application is split into small, independent services that work together like a team.
Each service does one job well, and all services communicate to form a complete system.
What You'll Learn in This Article
What microservices are and why they are important
How to build microservices step by step in .NET Core
A very simple, practical example
How Dependency Injection (DI) helps in making microservices scalable and easy to maintain
What are Microservices?
Microservices are a way of building software where an application is split into many small, independent services.
Each service:
Does one job only (for example: handling users, processing payments, or managing products).
Developers can be developed, tested, and deployed separately.
How Microservices Communicate
Microservices need to talk to each other to work as a complete system. This communication usually happens in two main ways:
REST APIs (HTTP)
The most common approach.
Services send requests like
GET,POST,PUT, andDELETEusing JSON over HTTP.Easy to use, widely supported, and great for external integrations.
gRPC (Google Remote Procedure Call)
A faster, modern alternative.
Uses binary data instead of plain text, making communication quicker and more efficient.
Ideal for real-time communication or when services need to exchange data frequently.
👉 Imagine a project team: Think of Microservices Like a Team of Developers
Each developer has a specific role — one works on UI, another on the database, another on APIs.
They work independently, but when their work is combined, the full application is delivered.
If one developer is on leave (one service fails), the rest of the team can still continue progress.
Microservices work the same way:
Each service has a focused responsibility.
Services can be built, deployed, and fixed independently.
Together, they form a complete, reliable application.
Why Microservices Matter
Scalability: You can scale only the service that needs more power (e.g., payments) instead of the whole app.
Flexibility: Teams can use different technologies for different services if needed.
Faster Development: Small services are easier to build and improve.
Fault Isolation: If one service fails, it doesn't crash the whole system.
👉 In short:
Microservices = small, self-contained services working together as one big application.
How to Implement Microservices in .NET Core
Let's understand microservices with a developer team example.
Imagine you are building a project with three developers:
UI Developer Service – focuses only on user interface.
API Developer Service – manages data flow and backend APIs.
Database Developer Service – takes care of storing and retrieving information.
Each developer works independently, but their work is combined to deliver the full project. Similarly, in .NET Core:
Step 1. Create Independent Services
In .NET Core, each microservice is a separate project (for example,
UiService,ApiService, andDbService).Each project has its own controllers, models, and data access logic.
👉 Just like each developer has their own tasks and tools.
Step 2. Define Communication
The UI Service (like the frontend developer) makes calls to the API Service (backend developer).
The API Service then fetches data from the DB Service (database developer).
Communication can happen using REST APIs or gRPC.
👉 Just like developers talk to each other through daily standups or messages to keep the project moving.
Step 3. Independent Deployment
Each service can be built and deployed separately.
If the API Service is updated, you don't need to redeploy the UI or DB Service.
👉 Just like one developer can push changes to their part of the code without waiting for the whole team.
Step 4. Bringing It Together
When all services are up and running:
The UI Developer Service calls the API Developer Service.
The API Developer Service calls the Database Developer Service.
Together, they deliver the complete functionality to the end user.
👉 Exactly how three developers working independently ship one complete project. With this example, you see how microservices are like a team of developers, each focusing on one area, but collaborating through APIs to complete the application.
Microservices in .NET Core: A Developer Team Code Example
We will create three microservices:
DbService – Database developer
ApiService – API developer
UiService – UI developer
Each service is independent, communicates via HTTP APIs, and uses Dependency Injection (DI) where needed.
DbService – Database Developer
// DbService/Controllers/DatabaseController.cs
using Microsoft.AspNetCore.Mvc;
using System.Collections.Generic;
namespace DbService.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class DatabaseController : ControllerBase
{
// Simulated database: dictionary stores task info
private static readonly Dictionary<int, string> data = new()
{
{ 1, "Task 1" },
{ 2, "Task 2" },
{ 3, "Task 3" }
};
// GET api/database/1
[HttpGet("{id}")]
public IActionResult GetData(int id)
{
// Check if the requested task exists
if (data.ContainsKey(id))
return Ok(new { Id = id, Task = data[id] });
// If task not found, return 404
return NotFound("Task not found");
}
}
}Comments / What is happening inside:
This service simulates a database.
Each task is stored in a dictionary.
When another service requests a task by ID, it returns the task or a 404.
Think of this as the Database Developer storing and providing information.
ApiService – API Developer
// ApiService/Controllers/TaskController.cs
using Microsoft.AspNetCore.Mvc;
using System.Net.Http;
using System.Text.Json;
using System.Threading.Tasks;
namespace ApiService.Controllers
{
[ApiController]
[Route("api/[controller]")]
public class TaskController : ControllerBase
{
private readonly HttpClient _httpClient;
// DI injects HttpClient so service can call DbService
public TaskController(HttpClient httpClient)
{
_httpClient = httpClient;
}
// GET api/task/1
[HttpGet("{id}")]
public async Task<IActionResult> GetTask(int id)
{
// Call DbService to get task info
var response = await _httpClient.GetAsync($"https://localhost:5001/api/database/{id}");
// If DbService returns error, propagate 404
if (!response.IsSuccessStatusCode)
return NotFound("Task not found");
// Read JSON response from DbService
var json = await response.Content.ReadAsStringAsync();
// Deserialize JSON into dynamic object
var task = JsonSerializer.Deserialize<dynamic>(json);
// Return to caller (UiService or client)
return Ok(new { Message = "Fetched by API Service", Task = task });
}
}
}
Join the conversation! Your thoughts help the community grow.