Skip to main content

Architecture Pattern: Logic Side-car

[!TIP] Definition: A "Logic Side-car" is a self-contained Service or Module that runs alongside the Legacy Monolith, performing complex calculations or operations without being intertwined with the legacy codebase.

1. Context & Problem

The Monolith Problem: Modifying core business logic in a legacy system (The "Big Ball of Mud") is high-risk. Dependencies are tangled, tests are missing, and side effects are unpredictable. The Rewrite Trap: A full rewrite takes too long and freezes business value delivery.

2. Solution: The Side-car

Instead of modifying the spaghetti code inside a Controller or a "God Service", we build a New, Pure Component (The Side-car) that sits next to the monolith.

2.1. Characteristics

  1. Read-Only (Mostly): It reads data directly from the legacy database (using EF or Dapper) but treats it as an "Input Stream".
  2. Stateless: It contains no persistent state of its own, besides potentially a cache.
  3. Result-Oriented: It produces a specific result (e.g., a "Priority Score", a "Recommendation", a "PDF") and writes it back to a specific, isolated column or table in the Legacy DB.
  4. Zero Coupling: It does NOT reference System.Web, HttpContext, or Legacy Controllers. It is a Pure Class Library.

2.2. Diagram

3. Implementation Strategy

3.1. The "Hook" (Integration Point)

The Monolith interacts with the Side-car only via a "Hook".

  • Sync Hook: A direct method call _sideCar.Calculate(orderId). (Use carefully).
  • Async Hook (Recommended): Fire-and-Forget (e.g., HostingEnvironment.QueueBackgroundWorkItem, Hangfire). The Monolith says "Order Updated", and the Side-car wakes up to recalculate.

3.2. Test Driven Development (TDD)

Because the Side-car is isolated from HttpContext and UI logic, it is trivial to test.

  • We can mock the Data Access Layer.
  • We can write hundreds of scenarios (Gherkin/Unit Tests) to perfect the algorithm before deploying.

4. Migration Path (Strangler Fig)

The Side-car is a Pre-Microservice.

  1. Phase 1 (Embedded): It runs as a DLL inside the Monolith's process for simplicity.
  2. Phase 2 (Isolated): It is moved to a separate container (Docker) running .NET 8, communicating via API/Events.
  3. Phase 3 (Sovereign): It takes ownership of its own data, treating the Legacy DB as a read-only source.

5. Examples

  • OMGT Priority Index: Calculates urgency scores based on legacy order data.
  • Complex Pricing Engine: Calculates price quotes based on rules, writing the final price to the DB.
  • PDF Generator: Reads order data, generates a PDF, saves URL to DB.