Domain Driven Design Context Mapping Created: 10 Jan 2026 Updated: 10 Jan 2026

Customer-Supplier

In the hierarchy of Strategic Design relationships, Customer-Supplier is one of the most collaborative patterns. It describes a situation where two teams have a strong dependency on each other, but unlike the Shared Kernel, they do not necessarily share the same code.

Instead, the relationship is defined by coordinated planning and prioritization.

1. What is Customer-Supplier?

In this relationship, the Downstream (Customer) and Upstream (Supplier) work together to ensure that the Supplier's output meets the Customer's needs.

  1. The Power Dynamic: The Downstream team (Customer) has a seat at the table during the Upstream team's (Supplier) planning sessions.
  2. The Commitment: The Upstream team is officially tasked with meeting the requirements of the Downstream team.
  3. The Integration: The teams must agree on a set of Automated Acceptance Tests to ensure that the Supplier's changes do not break the Customer's system.
Key Difference: In Conformist, the Upstream doesn't care about you. In Customer-Supplier, the Upstream is required to care about you.

2. Cinema Example: Booking & Promotions

Imagine the Booking Context (Customer) needs to apply discounts created in the Promotion Context (Supplier).

  1. The Request: The Booking team needs a way to validate a promo code before the user pays.
  2. The Supplier's Action: Even if the Promotion team didn't have this feature planned, they add it to their sprint because their "Customer" (the Booking team) requires it to function.

3. .NET Core Implementation Strategy

In a Customer-Supplier relationship, the technical implementation often involves a Contract-First approach or Consumer-Driven Contracts (CDC).

A. The Shared Contract (Published Language)

The teams agree on a DTO (Data Transfer Object) in a shared library or a Git submodule.

C#


// Defined together, maintained by the Supplier
public record DiscountValidationRequest(
string PromoCode,
decimal OrderTotal,
Guid CustomerId
);

public record DiscountValidationResponse(
bool IsValid,
decimal DiscountAmount,
string RejectionReason
);

B. The Automated Acceptance Test

The Customer writes a test that the Supplier must pass before they can release a new version. This prevents "breaking changes" from reaching production.

C#


[Fact]
public async Task Supplier_Should_Return_Valid_Discount_For_Generic_Code()
{
// This test lives in the Supplier's CI/CD pipeline but is defined by the Customer
var request = new DiscountValidationRequest("WELCOME2026", 100.0m, Guid.NewGuid());
var result = await _promotionService.Validate(request);
Assert.True(result.IsValid);
Assert.Equal(20.0m, result.DiscountAmount);
}

4. Comparison Table

FeatureShared KernelCustomer-SupplierConformist
Code SharingHigh (Shared Library)Low (Separate projects)None (Consumer adapts)
CommunicationVery High (Daily)High (Planning/Sprints)Low (Read the Docs)
AutonomyLowMediumHigh
RiskBreaking shared codeSupplier missing a deadlineUpstream changing the model

5. When to Choose Customer-Supplier?

  1. Internal Teams: Use this when both teams work for the same company and have aligned business goals.
  2. Strategic Core: Use this when the Downstream context is a "Core Domain" that needs specific data from a "Supporting Domain."
  3. Trust Level: Use this when there is enough trust to negotiate priorities but enough technical separation that you don't want to share a codebase.


Share this lesson: