CODESAMPLE

Microservices - C#

Share on:

The Microservices pattern structures an application as a collection of loosely coupled, independently deployable services, modeled around a business domain. Each service owns its data and communicates via lightweight mechanisms, often a RESTful API. This example demonstrates a simplified order and customer service interaction. It uses ASP.NET Core Web APIs for each service, showcasing C#’s strong typing and asynchronous capabilities. Dependency Injection is used for loose coupling. The services are intentionally minimal to focus on the pattern’s core concept of independent deployment and communication. Real-world implementations would involve more robust error handling, security, and service discovery.

// OrderService/OrderController.cs
using Microsoft.AspNetCore.Mvc;

namespace OrderService
{
    [ApiController]
    [Route("[controller]")]
    public class OrderController : ControllerBase
    {
        private readonly ICustomerService _customerService;

        public OrderController(ICustomerService customerService)
        {
            _customerService = customerService;
        }

        [HttpGet("{orderId}")]
        public async Task<IActionResult> GetOrder(int orderId)
        {
            // Simulate order retrieval
            var order = new Order { Id = orderId, CustomerId = 1 };

            // Call Customer Service to get customer details
            var customer = await _customerService.GetCustomer(order.CustomerId);

            if (customer == null)
            {
                return NotFound($"Customer with ID {order.CustomerId} not found.");
            }

            return Ok(new { Order = order, Customer = customer });
        }
    }

    public class Order { public int Id { get; set; } public int CustomerId { get; set; } }
}

// CustomerService/CustomerController.cs
using Microsoft.AspNetCore.Mvc;

namespace CustomerService
{
    [ApiController]
    [Route("[controller]")]
    public class CustomerController : ControllerBase
    {
        [HttpGet("{customerId}")]
        public Customer GetCustomer(int customerId)
        {
            // Simulate customer retrieval
            return new Customer { Id = customerId, Name = "Alice" };
        }
    }

    public class Customer { public int Id { get; set; } public string Name { get; set; } }
}

// Shared Interface (for inter-service communication)
public interface ICustomerService
{
    Task<Customer?> GetCustomer(int customerId);
}

//OrderService/Program.cs (Example of dependency injection)
using OrderService;
using CustomerService;
using Microsoft.Extensions.DependencyInjection;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();
builder.Services.AddScoped<ICustomerService, CustomerServiceProxy>(); // Use a proxy for external service calls

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

//CustomerService/Program.cs
var builder = WebApplication.CreateBuilder(args);

// Add services to the container.
builder.Services.AddControllers();

var app = builder.Build();

// Configure the HTTP request pipeline.
app.UseHttpsRedirection();
app.UseAuthorization();
app.MapControllers();

app.Run();

//OrderService/CustomerServiceProxy.cs (Proxy to call external service)
using System.Net.Http;
using System.Threading.Tasks;
using CustomerService;
using Newtonsoft.Json;

namespace OrderService
{
    public class CustomerServiceProxy : ICustomerService
    {
        private readonly HttpClient _httpClient;

        public CustomerServiceProxy(IConfiguration configuration)
        {
            _httpClient = new HttpClient();
            _httpClient.BaseAddress = new Uri(configuration["CustomerServiceUrl"]);
        }

        public async Task<Customer?> GetCustomer(int customerId)
        {
            var response = await _httpClient.GetAsync($"Customer/{customerId}");
            response.EnsureSuccessStatusCode();
            var customerJson = await response.Content.ReadAsStringAsync();
            return JsonConvert.DeserializeObject<Customer>(customerJson);
        }
    }
}