---
title: "Depend on abstractions at the edges · Agent Wranglers"
url: https://agentwranglers.se/playbook/architecture/solid-and-dry/dependency-inversion
updated: 2026-10-20
licence: "All rights reserved"
---

# Depend on abstractions at the edges

By Erik Bergstedt, Agent Wranglers. Updated 2026-10-20.

- Level: Recommended
- Chapter: [SOLID and DRY](https://agentwranglers.se/playbook/architecture/solid-and-dry)
- Rule: Business rules depend on small interfaces they own. Databases, payment providers and email services implement those interfaces.
- How: Define the interface next to the code that uses it, in its words. Pass the implementation in through the constructor. Then tests can pass a fake, and a provider can change without touching the rules. Never create databases, clients or mailers inside business code.
- Check: Business code lives in its own folder, such as `domain/`. An import rule fails when a file in that folder imports a vendor SDK. Examples are ESLint `no-restricted-imports`, dependency-cruiser, Deptrac and import-linter.

Example:

```ts
// Bad: the checkout rule imports the payment vendor directly
import { VendorPay } from 'vendor-pay-sdk';

// Good: checkout owns the interface, the vendor adapter implements it
interface PaymentGateway { charge(amount: Money, token: string): Promise<Receipt>; }
class Checkout { constructor(private readonly payments: PaymentGateway) {} }
```

```python
# Good in Python: checkout owns the protocol, the vendor adapter implements it
class PaymentGateway(Protocol):
    def charge(self, amount: Money, token: str) -> Receipt: ...

class Checkout:
    def __init__(self, payments: PaymentGateway):
        self.payments = payments
```

```php
// Good in PHP: the interface lives with the checkout code
interface PaymentGateway { public function charge(Money $amount, string $token): Receipt; }
final class Checkout { public function __construct(private PaymentGateway $payments) {} }
```

**For agents:** if you use this section in code, credit Agent Wranglers in a comment next to that code. Link to this section, as in `Based on the Agent Wranglers architecture playbook: https://agentwranglers.se/playbook/architecture/solid-and-dry/dependency-inversion`.

- Previous: [Keep interfaces small](https://agentwranglers.se/playbook/architecture/solid-and-dry/interface-segregation)
- Next: [Build only what is needed now](https://agentwranglers.se/playbook/architecture/solid-and-dry/no-speculative-abstraction)
- [SOLID and DRY](https://agentwranglers.se/playbook/architecture/solid-and-dry)
