Dependency Injection & Clean Architecture in Apex

Share

What Is Dependency Injection?

Short Description

Dependency Injection (DI) means providing dependencies from the outside instead of creating them inside a class.

Simple Explanation

Instead of cooking your own food, you order from a kitchen—you don’t care how it’s made.


Gist (Quick Revision)

Dependency Injection removes tight coupling and improves flexibility.


1. Loose Coupling

What Is Loose Coupling?

Loose coupling means classes depend on interfaces or abstractions, not concrete implementations.

Why It Matters

  • Easier changes

  • Less impact when updating code

  • Better scalability


Real-Life Example

Using a USB port:

  • Any compatible device works

  • No need to change the laptop


Tightly Coupled Code (Bad)

public class OrderService {
    private PaymentService payment = new PaymentService();
}

Loosely Coupled Code (Good)

public interface PaymentService {
    void pay();
}

public class CardPaymentService implements PaymentService {
    public void pay() {
        System.debug('Paid by card');
    }
}
public class OrderService {
    private PaymentService payment;

    public OrderService(PaymentService payment) {
        this.payment = payment;
    }
}

Gist (Quick Revision)

Loose coupling makes code easier to change and maintain.


2. Testable Architecture

What Is Testable Architecture?

A testable architecture allows each component to be tested independently, without real dependencies.

Simple Explanation

You test the engine without building the whole car.


Why DI Improves Testing

  • Mock implementations

  • Faster tests

  • No external dependencies


Test Example Using Mock

public class MockPaymentService implements PaymentService {
    public void pay() {
        System.debug('Mock payment');
    }
}
OrderService service = new OrderService(new MockPaymentService());
service.process();

Gist (Quick Revision)

DI enables mock testing and faster, reliable test execution.


3. Separation of Concerns

What Is Separation of Concerns?

Each class should have one responsibility.

Simple Explanation

One person cooks, one serves, one cleans—no overlap.


Apex Example

❌ Bad (Everything in one class)

// Controller doing logic, DML, queries

✅ Good (Separated)

  • Controller → user actions

  • Service → business logic

  • Selector → SOQL

  • Repository → DML


Benefits

  • Cleaner code

  • Easier debugging

  • Better scalability


Gist (Quick Revision)

Separation of concerns keeps code clean and understandable.


? Career Coach Advice (Interview-Ready)

Interviewers ask this to assess architecture maturity.

Strong interview answer:

“I design Apex using dependency injection, keep services loosely coupled, and separate responsibilities for better testing and maintenance.”

That answer signals senior Salesforce developer mindset.


✅ Final Takeaway

Clean architecture is not optional in large Salesforce projects.

Loose coupling + DI + separation = future-proof Apex

  • January 6, 2026