Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Monolithic Architecture

Overview

Monolithic Architecture là kiến trúc truyền thống trong đó toàn bộ ứng dụng được xây dựng như một đơn vị duy nhất. Tất cả components - UI, business logic, data access - đều nằm trong một codebase và được deploy cùng nhau.

Characteristics

┌─────────────────────────────────────────────────┐
│                 Web Server                       │
├─────────────────────────────────────────────────┤
│                  UI Layer                        │
│  ┌─────────────────────────────────────────┐   │
│  │           Controllers/Views             │   │
│  └─────────────────────────────────────────┘   │
├─────────────────────────────────────────────────┤
│              Business Logic Layer              │
│  ┌─────────────────────────────────────────┐   │
│  │     Services, Business Rules            │   │
│  └─────────────────────────────────────────┘   │
├─────────────────────────────────────────────────┤
│                Data Access Layer                │
│  ┌─────────────────────────────────────────┐   │
│  │     Repositories, ORM, SQL              │   │
│  └─────────────────────────────────────────┘   │
├─────────────────────────────────────────────────┤
│                  Database                        │
└─────────────────────────────────────────────────┘

Structure

// Monolithic Project Structure
MyApp/
├── Controllers/
│   ├── ProductsController.cs
│   ├── OrdersController.cs
│   └── CustomersController.cs
├── Services/
│   ├── ProductService.cs
│   ├── OrderService.cs
│   └── CustomerService.cs
├── Models/
│   ├── Product.cs
│   ├── Order.cs
│   └── Customer.cs
├── Repositories/
│   ├── ProductRepository.cs
│   ├── OrderRepository.cs
│   └── CustomerRepository.cs
├── Views/
│   ├── Products/
│   ├── Orders/
│   └── Customers/
└── AppDbContext.cs

Implementation Example

// Controllers/OrdersController.cs
public class OrdersController : Controller
{
    private readonly OrderService _orderService;
    
    public OrdersController(OrderService orderService)
    {
        _orderService = orderService;
    }
    
    [HttpGet]
    public async Task<IActionResult> Index()
    {
        var orders = await _orderService.GetAllOrdersAsync();
        return View(orders);
    }
    
    [HttpPost]
    public async Task<IActionResult> Create(CreateOrderViewModel model)
    {
        if (!ModelState.IsValid)
            return View(model);
            
        await _orderService.CreateOrderAsync(model);
        return RedirectToAction(nameof(Index));
    }
}

// Services/OrderService.cs
public class OrderService
{
    private readonly OrderRepository _orderRepository;
    private readonly ProductRepository _productRepository;
    private readonly EmailService _emailService;
    
    public OrderService(
        OrderRepository orderRepository,
        ProductRepository productRepository,
        EmailService emailService)
    {
        _orderRepository = orderRepository;
        _productRepository = productRepository;
        _emailService = emailService;
    }
    
    public async Task CreateOrderAsync(CreateOrderViewModel model)
    {
        var order = new Order
        {
            CustomerId = model.CustomerId,
            OrderDate = DateTime.Now,
            Status = OrderStatus.Pending
        };
        
        foreach (var item in model.Items)
        {
            var product = await _productRepository.GetByIdAsync(item.ProductId);
            order.AddItem(product, item.Quantity);
        }
        
        await _orderRepository.SaveAsync(order);
        
        await _emailService.SendOrderConfirmation(order);
    }
}

// Repositories/OrderRepository.cs
public class OrderRepository
{
    private readonly AppDbContext _context;
    
    public OrderRepository(AppDbContext context)
    {
        _context = context;
    }
    
    public async Task SaveAsync(Order order)
    {
        _context.Orders.Add(order);
        await _context.SaveChangesAsync();
    }
}

Advantages

AdvantageDescription
SimplicityEasy to develop và debug
PerformanceIn-process calls are fast
ConsistencySingle codebase, shared resources
TransactionEasy to maintain ACID transactions
DeploymentSimple deployment (single package)
DevelopmentGood for small teams

Disadvantages

DisadvantageDescription
ScalabilityKhó scale theo component
TechnologyHard to adopt new technologies
ReliabilityOne failure affects entire app
DeploymentPhải redeploy toàn bộ app
DevelopmentCodebase grows large, hard to maintain
CouplingTightly coupled components

When to Use

  • Small to medium applications
  • Teams mới hoặc limited experience
  • Rapid prototyping
  • Applications với tight integration requirements
  • Projects với limited scope

When NOT to Use

  • Large, complex applications
  • Applications requiring frequent scaling
  • Teams cần technological flexibility
  • Microservices-based requirements

Scaling Strategies

Vertical Scaling

// Load balancing configuration
services.AddLoadBalancing(options =>
{
    options.MaxParallelRequests = 10;
});

Horizontal Scaling (Multiple Instances)

// Using sticky sessions or session state
services.AddDistributedMemoryCache();
services.AddSession(options =>
{
    options.Cookie.Name = ".MyApp.Session";
    options.IdleTimeout = TimeSpan.FromMinutes(20);
});

Database Scaling

// Read/Write splitting
public class OrderRepository
{
    private readonly AppDbContext _readContext;
    private readonly AppDbContext _writeContext;
    
    public async Task<List<Order>> GetOrdersAsync()
    {
        return await _readContext.Orders.ToListAsync();
    }
    
    public async Task SaveAsync(Order order)
    {
        await _writeContext.Orders.AddAsync(order);
        await _writeContext.SaveChangesAsync();
    }
}

Modern Monolithic Approaches

// Modular Monolith - Separate by feature
src/
├── Modules/
│   ├── Orders/
│   │   ├── OrdersController.cs
│   │   ├── OrderService.cs
│   │   ├── OrderRepository.cs
│   │   └── OrdersModule.cs  // Module registration
│   ├── Products/
│   │   ├── ProductsController.cs
│   │   ├── ProductService.cs
│   │   ├── ProductRepository.cs
│   │   └── ProductsModule.cs
│   └── Customers/
│       ├── CustomersController.cs
│       ├── CustomerService.cs
│       ├── CustomerRepository.cs
│       └── CustomersModule.cs
└── Shared/
    ├── Database/
    ├── Logging/
    └── Authentication/

Best Practices

  1. Use Layers: Separate concerns within the monolith
  2. Modularize: Group code by feature, not by technical layer
  3. Configuration: Externalize configuration
  4. Logging: Implement centralized logging
  5. Monitoring: Add health checks và metrics

Migration Path

Monolithic → Modular Monolithic → Microservices
    ↓              ↓                    ↓
 Single app    Feature modules     Distributed
                                             

References