Building Microservices with .NET
Welcome to the official Microsoft tutorial on building robust microservices using .NET. Follow the sections below to create, test, and deploy scalable services.
Prerequisites
- .NET 8 SDK or later
- Docker Desktop
- Visual Studio 2022 or VS Code
- Basic knowledge of REST APIs
Step 1: Create a New Web API Project
Open a terminal and run the following command:
dotnet new webapi -n ProductService
This command scaffolds a minimal Web API project named ProductService
.
Step 2: Define the Domain Model
Add a new file Models/Product.cs
with the following content:
namespace ProductService.Models;
public class Product
{
public int Id { get; set; }
public string Name { get; set; } = string.Empty;
public decimal Price { get; set; }
}
Step 3: Add an In‑Memory Repository
Create Repositories/IProductRepository.cs
:
using ProductService.Models;
namespace ProductService.Repositories;
public interface IProductRepository
{
IEnumerable<Product> GetAll();
Product? GetById(int id);
void Add(Product product);
void Update(Product product);
void Delete(int id);
}
And an implementation Repositories/InMemoryProductRepository.cs
:
using ProductService.Models;
namespace ProductService.Repositories;
public class InMemoryProductRepository : IProductRepository
{
private readonly List<Product> _products = new();
public IEnumerable<Product> GetAll() => _products;
public Product? GetById(int id) => _products.FirstOrDefault(p => p.Id == id);
public void Add(Product product) => _products.Add(product);
public void Update(Product product)
{
var index = _products.FindIndex(p => p.Id == product.Id);
if (index != -1) _products[index] = product;
}
public void Delete(int id) => _products.RemoveAll(p => p.Id == id);
}
Step 4: Register Services
Update Program.cs
to add the repository to the DI container:
builder.Services.AddSingleton<IProductRepository, InMemoryProductRepository>();
Step 5: Create the Controller
Add Controllers/ProductsController.cs
:
using Microsoft.AspNetCore.Mvc;
using ProductService.Models;
using ProductService.Repositories;
namespace ProductService.Controllers;
[ApiController]
[Route("api/[controller]")]
public class ProductsController : ControllerBase
{
private readonly IProductRepository _repo;
public ProductsController(IProductRepository repo) => _repo = repo;
[HttpGet]
public ActionResult<IEnumerable<Product>> Get() => Ok(_repo.GetAll());
[HttpGet("{id}")]
public ActionResult<Product> Get(int id)
{
var product = _repo.GetById(id);
return product is null ? NotFound() : Ok(product);
}
[HttpPost]
public ActionResult<Product> Post(Product product)
{
_repo.Add(product);
return CreatedAtAction(nameof(Get), new { id = product.Id }, product);
}
[HttpPut("{id}")]
public IActionResult Put(int id, Product product)
{
if (id != product.Id) return BadRequest();
_repo.Update(product);
return NoContent();
}
[HttpDelete("{id}")]
public IActionResult Delete(int id)
{
_repo.Delete(id);
return NoContent();
}
}
Step 6: Run Locally
Start the API:
dotnet run
Open Swagger UI to test the endpoints.
Step 7: Containerize the Service
Create a Dockerfile
in the project root:
FROM mcr.microsoft.com/dotnet/aspnet:8.0 AS base
WORKDIR /app
EXPOSE 80
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
WORKDIR /src
COPY ["ProductService.csproj", "./"]
RUN dotnet restore "./ProductService.csproj"
COPY . .
RUN dotnet publish "ProductService.csproj" -c Release -o /app/publish
FROM base AS final
WORKDIR /app
COPY --from=build /app/publish .
ENTRYPOINT ["dotnet", "ProductService.dll"]
Build and run the container:
docker build -t productservice .
docker run -d -p 8080:80 productservice