System ArchitectureArchitect, Backend Developer

What does the "Dependency Inversion" principle mean in architectural design, and how is it different from simple dependency inversion in code?

Pass interviews with Hintsage AI assistant

Answer.

Dependency Inversion Principle (DIP) is an architectural principle that states:

  • High-level modules should not depend on low-level modules. Both types should depend on abstractions (interfaces).
  • Abstractions should not depend on details, details should depend on abstractions.

This means that business logic (for example, the order handling service) should not know and directly use specific implementations of infrastructure (for example, a class that implements email sending) but should work through an abstraction (interface), which you inject via a DI container or manually.

Example code in C#:

public interface IEmailSender { void Send(string to, string message); } public class SmtpEmailSender : IEmailSender { public void Send(string to, string message) { // Implementation of sending email } } public class OrderService { private readonly IEmailSender _emailSender; public OrderService(IEmailSender emailSender) { _emailSender = emailSender; } public void PlaceOrder(string customer) { // business logic _emailSender.Send(customer, "Your order is placed!"); } }

Key features:

  • Allows easy substitution of implementation details (e.g., injecting a mock in tests).
  • Increases the testability and extensibility of the architecture.
  • Provides loose coupling of modules.

Tricky questions.

Is DIP just dependency injection via constructors?

No. DIP is about separating abstractions from implementations. Dependency Injection (DI) is only a tool through which DIP is realized. DIP can also be implemented without a DI container by manually ensuring the separation of abstractions and details.

If you have one implementation of the interface, is DIP mandatory?

Yes, the principle still applies if extension is possible. Introducing abstractions prepares the system for changes in requirements without modifying high-level code. Even with one implementation of the interface, loose coupling facilitates testing and system development.

Can you violate DIP by using logic in factories or service locators?

Yes. If a factory or service locator knows about implementation details and dynamically binds them without using an interface on the client side, DIP is violated despite the external presence of abstractions.