Download as pptx, pdf, or txt
Download as pptx, pdf, or txt
You are on page 1of 64

The Dependency Inversion Principle

Elias Fofanov

http://engineerspock.com
Outline

• Definition of DIP
• What is a dependency and what types of dependencies exist
• Inversion of Control and Dependency Injection
• Problems caused by DIP violation
• Refactoring to a better design
• Architectural implications of adhering to DIP
• IoC-containers and how to build a simple one on your own
• Non-trivial example of an application with an IoC-Container
• Common smells of DIP violation
• Conclusion
Next Video
Definition of DIP
Definition of DIP
DIP

• DIP is about decoupling!


• Coupling indicates how dependent modules are on the inner workings of each other
• DIP is applicable both at the source code and binary level
Low coupling is often a sign of a well-structured
computer system and a good design, and when
combined with high cohesion, supports the general
goals of high readability and maintainability.
High-level modules should not depend on low-level
modules. Both should depend on abstractions.

Abstractions should not depend on details. Details should


depend on abstactions.
Next Video
Dependencies
Dependencies
Types of Dependencies

• Framework
• 3rd party libs
• External Systems like File System, Database, any system resource
• Dependency on a custom type built on top of the .NET framework
Policy depends on Details

• High-level objects of the domain layer directly depend on


UI
low-level objects of the infrastructural layer
• It’s hard to replace coupled dependencies
• We can solve any problem by introducing an extra level of
indirection
Person

PersonRepository
Policy doesn’t depend on Details

UI • IPersonRepository is a seam which inverts the


dependencies

Person

<<interface>>
IPersonRepository

PersonRepository
Policy depends on Details

<<interface>>
A Interface
+f()

+f()
Next Video
Volatile and Stable Dependencies
Volatile and Stable Dependencies
What dependencies should we abstract away?
Dependencies can be divided into two camps:
• Volatile
• Stable
Volatile Dependencies

A dependency is volatile if any of the following criteria is true:


• dependency itself depends on the environment (web servers, db)
• dependency doesn’t yet exist and is still under development
• dependency which is not installed on all machines of developers
• dependency has a nondeterministic behavior (randomizers inside)

If none of these true, a dependency is stable.


Volatile dependencies are those which we want to
abstract away by introducing levels of indirection.
Next Video
Definitions of IoC and DI
Definitions of IoC and DI
DIP via DI

<<interface>>
A Interface
+f()

+f()
Inversion of Control (IoC)

• IoC reflects the model of relationships between a caller and a callee


• Classic flow of control implies that a client has a full control over the environment and
sequence of calls to library methods
• IoC implies that a callee takes control over some calls between caller and callee.
(callbacks is the simplest form)
• Frameworks rule the client’s code
DIP

• DIP is a detailed version of IoC


• Concretizes that “High-level modules should not depend on low level modules”
Dependency injection (DI) is a set of software design
principles and patterns that enable us to develop
loosely coupled code.
IoC and DI

• IoC can exist without DI


• The main way to perform the inversion of control is to apply DI techniques
Next Video
DIP Violation Demo
DI Techniques
Constructor Injection

• Protects the invariants

Possible pitfall:
• tends to accumulate many dependencies
• smell of SRP violation, consider extracting a class
Constructor Injection

Possible pitfall:
• several dependencies tend
to be passed in together
interface IDependency1 { } class Infrastructure : IInfrastructure
interface IDependency2 { } {
interface IDependency3 { } public Infrastructure(IDependency1 d1,
interface IDependency4 { } IDependency2 d2,
IDependency3 d3,
class ViewModel IDependency4 d4)
{ { }
public ViewModel(IDependency1 d1, }
IDependency2 d2,
IDependency3 d3, class ViewModel
IDependency4 d4) {
{ } public ViewModel(IInfrastructure infrastructure)
} { }
}
Constructor Injection

Possible pitfall:
• Non-obligatory dependencies

public class Customer {


private ILogger _logger = new Logger();

public Customer() {}

public Customer(ILogger logger) {


_logger = logger;
}
}
Constructor Injection

Possible pitfall:
• 3rd party framework imposes a public default constructor

public class Customer {


private ICustomerRepo _repo;

//HAVE TO EXPOSE
public Customer() {}

public Customer(ICustomerRepo repo) {


_repo = repo;
}
}
Constructor Injection

Possible pitfall:
• a certain dependency is used only in a single method

=> use method injection instead


Property Injection

Possible pitfall:
• Breaks encapsulation

public class Customer


{
public Customer()
{
}

public ILogger Logger { get; set; } = new Logger();


}
Method Injection

Apply if only one method uses a dependency


or that dependency changes from one call to another.

public interface ICurrencyRateProvider {


int GetCurrencyRate(string currency);
}

public class PaymentService {


public static Money CalculatePayment(ICurrencyRateProvider currencyRate) {
return new Money();
}
}

Pitfalls:
• SRP Violation
• IoC-Containers don’t inject dependencies into methods
Next Video
Architectural Implications
Architectural Implications
Application Boundaries

<<interface>>
A Interface
+f()

+f()

• Plugins can be deployed and developed independently


• Divide the system by boundaries and invert the dependencies that cross those boundaries
• Plugins define the boundaries of a system
Data-Centric Model

Utils

Business
UI The Database
Logic

• Data and Schema rule the world


• Logic in SQL Stored Procedures
• SQL is suited for tuples processing,
not for modeling objects relationships
Domain-Centric Model

Utils

UI Domain and BL Database

• Domain is the Core


• Domain is Stable
Enlarged Domain-Centric Model
Enlarged Domain-Centric Model

• Ports and Adapters architecture


• Ports are seams we introduce by
extracting interfaces
and
adapters are plugins which come from
the boundary of a system
• strive to keep the graph as flatter as
you can
Enlarged Domain-Centric Model

Who is responsible for keeping the control over the


dependencies instantiation and their lifetime? App Partition

Answer: “Main as the infrastructural point.”

Factory Main

Factory
Factory Impl
• Conforms to “Single Choice” principle Main Partition
Factory
• Only Main knows about dependencies Impl
and their relationships
Next Video
Pure DI and IoC-Containers
Pure DI and IoC-Containers
Pure DI and IoC-Containers

Two ways of dealing with DI:


• Manually create all the dependencies injecting them explicitly – “Pure DI”
• Use an IoC-Container (also knows as DI-Containers)
IoC-Containers

IoC-Container is a framework which helps to apply DI.


• Injects dependencies automatically
• Dependencies configuration
• Knows everything about dependencies
How IoC-Container Works

IoC-Container recursively creates all the required dependencies.


Next Video
Building a Simple IoC-Container
Startup event
var b = new Bootstrapper();
WPF ConfigureRuntime()
b.Start();

creates ShellView Framework ShellViewModel creates


WPF • locates ShellViewModel • MainViewModel via IoC
• calls IoC.Get<ShellViewModel> • MainView via data templates

WindowManager creates:
• ViewModel via IoC
clicks on a button MainViewModel calls • locates View
User
IWindowManager.Show(typeof(ViewModel)) • creates View
• Sets its data context to a newly
created ViewModel
Next Video
Common Smells of DIP Violation
Common Smells of DIP Violation
Common Smells

• A class explicitly creates one or more dependencies hiding them from a client
• A class uses nondeterministic dependencies like DateTime or Random
• extract a class which works with non-deterministic dependencies and cover it by integration tests
• create an adapter
• A class uses static dependencies, very often singletons

To remove the smell:


• Extract a layer of indirection and make high-level policies independent of low-level details
• Adhere to the SRP
Next Video
Conclusion
Conclusion
Conclusion

 DIP implies that high-level policies should not depend on low-level details
 Two major types of dependencies: stable and unstable (or volatile)
Unstable dependencies are those to which we want to apply the inversion of control
 What IoC and DI are and how they’re related to the DIP and to each other
 3 techniques of DI:
 constructor injection which should be used in 95% of cases
 property and method injection
 Adhering to DIP leads to a plugin architecture which is known as the
“Ports and Adapters” architecture
 There should be a single place which knows everything about application dependencies and their
relationships and this place is Main.
 Manual dependency injection may become tedious;
that’s why IoC-containers exist, they help to simplify DI in difficult cases
 How to build a simple IoC-container and
 Example of a real-world application which relies on an IoC-container and sets it up in Main
 Common smells of the DIP violation and how to fix them
Learn Metaprinciples in the next section.
Next Video
SRP Outline
Single Point Slide

Good for making a single point, or


recapping a particular concept that
you’ve just covered.
You can either use both text
columns, a single text column, or
half and half with an accompanying
image.
20XX 20XX 20XX 20XX
Multi Point Slide

● Good for making multiple points in one slide, or for anything that needs a
large amount of space in general
● In general between three to five bullet points is about right, any more than
that and everything starts to look a bit like a wall of text
● Also ideal for large charts, still images - animated GIFs can work as well if
you’re using Google Slides
Using Diagrams and Shapes

Step 3
Step 2 We challenge you to create
Step 1 and build your own examples
We show you how to analyse
We help you understand
and apply what you’ve seen
and remember key points
This format is ideal for quick
summaries and explaining the
reasoning behind certain
Why? decisions.
Development can be
Because this is the responsible
thing to do opinionated; and that’s totally
fine. Just bring the audience
along with you.

You might also like