Dependency Injection in Android
Vasiliy Zukanov
Freelancer, blogger, online instructor
www.TechYourChance.com
Paris	city	planning:
Software	Architecture Software	Design
Do	you	use	dependency	injection?
Would	you	like	to	use	it?
Dependency	injection:
public class SomeClient {
private final SomeService mSomeService;
public SomeClient() {
mSomeService = new SomeService();
}
}
public class SomeClient {
private final SomeService mSomeService;
public SomeClient(SomeService someService) {
mSomeService = someService;
}
}
That’s	bad	because	UNIT	TESTS That’s	good	because	UNIT	TESTS
Dependency	injection	is	just	passing	services	
into	clients	from	outside!
Thank	you	(talk	is	over)!?
Dependency	injection	puzzler	#1:
public class DataAggregator {
private final List<Data> mData;
public SomeClient() {
mData = new LinkedList<>();
}
public void addData(Data data) {
mData.add(data);
}
public List<Data> getAllData() {
return mData;
}
}
Does	this	violate	dependency	injection	principles?
Dependency	injection	puzzler	#2:
public class SomeClient {
private final SomeService1 mSomeService1;
private final SomeService2 mSomeService2;
public SomeClient(ServiceLocator serviceLocator) {
mSomeService1 = serviceLocator.getService(SomeService1.class);
mSomeService2 = serviceLocator.getService(SomeService2.class);
}
}
Constructor	argument,	so	everything	is	kosher,	right?
Dependency	injection	puzzler	#3:
Why	dependency	injection	frameworks	exist,	and	why	are	
they	so	complex?
Dependency	injection	puzzler	#4:
If	all	clients	get	services	from	outside,	where	all	these	
services	being	instantiated?
That’s	the	most	important	question	in	context	of	dependency	injection
Looks	like	dependency	injection	is	not	that	
simple	after	all!
Dependency	injection,	this	time	for	real:
The	main	characteristic	of	dependency	injection	is	segregation	of	
application’s	logic	into	two	sets	of	classes:
Functional	set:	
contains	classes	that	encapsulate	core	application’s	functionality
Construction	set:	
contains	classes	that	resolve	dependencies	and	instantiate	objects	from	
functional	set
Functional	and	construction	sets	must	be	disjoint.
Dependency	injection,	schematically:
Application
Construction Set
class
Functional Set
classintegration
Segregation	of	classes	into	Construction	and	Functional	sets	is	
manifestation	of	Separation	of	Concerns
Separation	of	concerns	at	application	level	of	
abstraction	is…
…	architectural	pattern!
Dependency	Injection	=	Architectural	Pattern
Benefits	of	dependency	injection:
Easier	reuse	of	functionality
Better	maintainability
Clients	aren’t	coupled	to	services	construction	details
Clients	aren’t	coupled	to	services	lifecycle
Better	testability
One	of	the	most	beneficial	architectural	
patterns	in	object-oriented	design!
But	it’s	an	overkill	on	small	projects,	right?
Dependency	injection	ROI	analysis:
Return:	all	the	benefits	discussed	previously
Investment:
You	know	how	to	do	DI:	~1	hour	on	a	greenfield	project
You	learn	from	good	resource:	several	days	on	a	greenfield	project
You	learn	from	bad	resource:	several	weeks	(months,	never?)	on	a	greenfield	
project
Very	difficult	to	introduce	dependency	injection	
in	existing	codebase!
Dependency	injection	frameworks:
Application
Construction Set
class
Functional Set
classintegration
Dependency	injection	frameworks	are	templates	for	implementation	
of	Construction	set
DI framework
Warning	about	dependency	injection	frameworks:
“… I don’t want [Dependency Injection]
framework code smeared all through my
application. I want to keep frameworks
nicely decoupled and at arms-length from
the main body of my code. I don’t want to
have @Inject attributes everywhere and
bind calls hidden under rocks.”
- Robert “Uncle Bob” Martin
Dependency	injection	best	practices
Use	constructor	injection	by	default:
The	only	exceptions	are	either	classes	that	you	don’t	construct	
(Activity,	Service,	etc.),	or	classes	that	must	be	constructed	using	
specific	constructor	(Fragment)
Don’t	violate	the	Law	of	Demeter:
public class SomeClient {
private final SharedPreferences mSharedPreferences;
public SomeClient(Context context) {
mSharedPreferences = context.getSharedPreferences("prefs", Context.MODE_PRIVATE);
}
}
public class SomeClient {
private final SharedPreferences mSharedPreferences;
public SomeClient(SharedPreferences sharedPreferences) {
mSharedPreferences = sharedPreferences;
}
}
Discriminate	between	objects	and	data	structures:
Objects	expose	behavior (e.g.	UpdateUserDetailsUseCase)
Data	structures	(entities,	value	objects,	data	classes,	List,	String,	etc.)	
expose	data (e.g.	User)
Even	though	both	objects	and	data	structures	extend	Object	class	in	
Java,	they	represent	different	concepts.
Dependency	injection	applicable	only	to	objects!	
Rule	of	thumb:	no	data	structures	in	Construction	set
Exclude	Android	Views	from	dependency	injection:
Don’t	add	Android	Views	to	objects	graph
Don’t	inject	into	Android	Views	from	Construction	set
Rule	of	thumb:	no	Android	Views	in	Construction	set
Dependency	injection	best	practices:
Use	constructor	injection	by	default
Don’t	violate	the	Law	of	Demeter
Discriminate	between	objects	and	data	structures
Exclude	Android	Views	from	dependency	injection
Who	would	like	to	use	dependency	injection?
My	advanced	Android	development	courses	(links	on	my	blog):
Dependency	Injection	in	Android	with	Dagger	2
Android	Unit	Testing	and	Test	Driven	Development
Android	Applications	Architecture
www.TechYourChance.com
Questions
Thank	you!

Dependency Injection in Android - Vasiliy Zukanov