SlideShare a Scribd company logo
Dependency Injection:
Why is it awesome
and why should I care?
Nolan Erck
About Me
● Consultant (southofshasta.com)
● Software Development, On-site Training, Design
● Using ColdFusion since 1999 (4.x)
● Other stuff: C++, Java, jQuery, PHP, .NET, HTML5,
Android, you get the idea...
● Manager of SacInteractive
● Reformed Video Game Developer (Grim Fandango,
SimPark, StarWars Rogue Squadron, etc).
● Music Junkie
Dependency Injection
Dependency Injection
Dependency Injection
Today's Agenda
● What is Dependency Injection?
● When/why do I want it in my projects?
● Intro to Bean Management
● Intro to Aspect Oriented Programming (AOP)
● Intro to Inversion of Control (IOC)
● Other info
● Questions
Prerequisites
● Have some experience building classes and
objects.
● Don't need to be an expert.
● Don't need to have used an MVC framework.
● DI frameworks can be totally separate.
● And 1 more thing you need to know...
Prerequisites
● Know that Object Oriented Programming is
hard.
● And some of it is confusing at first.
● And that's NORMAL.
Dependency Injection
What is Dependency Injection?
● A “design pattern”
● $6 phrase for “a way to organize your classes so
they work together in a flexible way”.
● Like a for() loop, if(), array[]
– Reusable technique, based around objects.
● There are lots of design patterns:
– Dependency Injection is 1 design pattern
– Inversion of Control (IOC), Aspect Oriented Programming
(AOP) and Bean Management are all “variations on that
theme”.
– There are lots of others too.
What is Dependency Injection?
● It's not platform specific.
● Available for ColdFusion, Java, .NET,
JavaScript, etc.
● For today's preso:
● Using mostly pseudocode.
● Some keywords will change.
● All the concepts work the same across libraries and
languages.
Why / When Do I Want
D/I In My Projects?
● Short answer:
When you have lots of classes that talk to each
other, want to keep code organized, and make it
easy to swap different “types” of objects in/out of
your application.
Why / When Do I Want
D/I In My Projects?
● Short answer:
When you have lots of classes that talk to each
other, want to keep code organized, and make it
easy to swap different “types” of objects in/out of
your application.
● Longer answer:
That's what the rest of the slides are for...
Does this mean...
● I have to rebuild my entire app to use D/I?
● No. But you might get more benefits if you make a
few changes to legacy code along the way.
● I have to learn a new way to code all my classes?
● No. You can leave everything as-is.
– The nice thing about D/I is you can use it or not
use it. If you want to write code the “old way” in
part of your app, there's nothing stopping you
from doing so. It will all still work as-is.
● Neat huh? Let's learn a bit more, shall we?
Bean Management
What's a Bean?
A “thing” your D/I framework knows about.
class User{ … }
class DateUtils {…}
In your DI framework:
bean id=”myUser” class=”User”
bean id=”myDateUtils” class=”DateUtils”
(Exact syntax varies between DI libraries.)
Bean Management
class A {
public class A() {...}
}
class B{
public class B(A a)
{ … }
}
class C {
public class C(B b)
{ … }
}
class D{
public class D(C c)
{...}
}
So if I -JUST- want a D object made...
Bean Management
I have to do all this...
A a = new A();
B b = new B( a );
C c = new C( b );
D d = new D( c );
4 lines of code. The first 3 are “boilerplate” to create the
variables I need to make a D.
Multiply that out over all the objects in your app...
= a LOT of boilerplate code!
Another way to say it:
“D depends on A, B and C being made first”.
Bean Management
With a D/I library that does Bean Management, you'd write
something like this instead...
D d = ColdSpring.getBean( “D” );
4 lines of code just became 1. And no more boilerplate stuff!
You tell your D/I framework “I need a D. Go find out what D
depends on, make those as needed, and hand me back D when
you're done.”
(“ColdSpring” is a placeholder here for any D/I framework. They
all work about the same.)
Bean Management
● Quasi Real World Example.
● Mailing department wide messages.
● Mail Service CFC
● Needs a Department CFC to know which
Department is being emailed.
● Department needs a Department DAO for it's SQL
stuff.
● And a SecurityLogin CFC to make sure it's
validated/logged in/whatever.
Bean Management
● Old Way
mySecLogin = CreateObject( “component”, “SecurityLogin”);
myDeptDAO = CreateObject(“component”,“DepartmentDAO”);
dept = CreateObject( “component”, “Department” );
dept.init( mySecLogin, myDeptDAO );
mailSvc = CreateObject( “component”, “MailService” );
mailSvc.init( dept );
mailSvc.sendEmail();
Bean Management
● New Way
ColdSpring.getBean( “mailService” ).sendMail();
Bean Management
● New Way
ColdSpring.getBean( “mailService” ).sendMail();
Yes, 1 line of code.
Yes, it is THAT easy.
(I'm over simplifying a little.)
Bean Management
● So how does the D/I framework “know” that I need an A, B and
C to make a D object?
● Varies a little from framework to framework.
● Configuration based: XML file that “describes” the relationship
between the objects.
● (ColdSpring, Spring)
– Nice for, say, white-box testing w/ hands-on QA team.
● Convention based:
● Works automatically by which folders you store classes in,
and how the classes are named.
● DI/1, WireBox
● Just pick one and try it out, they all do the same core “things”.
Inversion of Control (IOC)
Inversion of Control (IOC)
● Fancy term for “flipping” some code around
from the “traditional” or “normal” way you'd build
objects.
● Instead of building an Employee object, then a
Department object, then putting the Employee
IN the Department.
● You say “get me a fully populated/constructed
Department”.
● Magic happens, automatically building the
Employee object for you.
Inversion Of Control (IOC)
class RockGroup
{
private String groupName;
public String getGroupName(){
return groupName;
}
public void setGroupName(String name) {
this.groupName = name;
}
}
No Constructor.
“groupName” is private.
So we have to call the
setter to initialize the
variable with something.
Inversion Of Control (IOC)
With regular code, we'd do this:
String myBandName = “depeche mode”;
RockGroup rg = new RockGroup();
rg.setGroupName( myBandName );
That works but...
Every time I want to provide a different default
value, I have to change code, and recompile.
Inversion Of Control (IOC)
What if we could provide that default value in a
“config file”, outside of code?
And whenever we create a RockGroup object, it
automatically gets a default value for
groupName passed in at that instant?
You can!
Inversion Of Control (IOC)
Using a D/I framework, you can have a “config” that notes default
values for your classes:
<class name=”RockGroup”>
<property name=”groupName” value=”Depeche Mode”/>
</class>
rg = ColdSpring.getBean( “RockGroup” )
...any time I make a RockGroup, it will automatically initialize the
“groupName” variable to the default value I provided. No extra lines of
code. And changing this default is now done in a config file. No
recompiling code to change it!
Inversion Of Control (IOC)
What about classes inside of other classes?
● AKA “Composition”, the “has a” relationship.
● Kind of the same thing...
Inversion Of Control (IOC)
class RockGroup{
private String groupName;
public String getGroupName()
{ … }
public void
setGroupName( String name )
{…}
private Musician singer;
public Musician getSinger()
{ … }
public void setSinger( Musician
m ) {…}
}
class Musician{
private String name;
private int yearsSober;
private int age;
public String getName()
{ return name; }
public void setName(String n)
{ this.name = n; }
public int getYearsSober() { … }
public void setYearsSober(int y)
{ … }
public void setAge( int a ){...}
public int getAge(){ return age; }
}
Inversion of Control (IOC)
With straight code...
Musician m = new Musician();
m.name = “David Lee Roth”;
m.age = 50;
m.yearsSober = 10;
RockGroup rg = new RockGroup();
rg.setGroupName( “Van Halen” );
rg.setSinger( m );
Inversion of Control (IOC)
With D/I...
RockGroup rg = Spring.getBean(“RockGroup”);
Inversion Of Control (IOC)
The Musician class has a String property, that
gets initialized just like the String property in
RockGroup. Ditto for the “int” properties, etc:
Spring.getBean( “Musician” );
– “name” will always be whatever is in my config for the
Musician class.
<class name=”Musician”>
<property name=”name” value=”David Lee Roth” />
<property name=”age” value=”50” />
<property name=”yearsSober” value=”10” />
</class>
Inversion Of Control (IOC)
You can also refer to other classes in the config, and “inject” them
into each other, just like we “injected” the String and int into
Musician:
<class name=”Singer” id=”mySingerBean”>
<property name=”name” value=”David Lee Roth” />
<property name=”yearsSober” value=”10” />
<property name=”age” value=”50” />
</class>
<class name=”RockGroup”>
<property name=”groupName” value=”Van Halen” />
<property name=”singer” ref=”mySingerBean” />
</class>
Inversion Of Control (IOC)
So now when I do this...
rg = DIFramework.getBean( “RockGroup” );
● rg will be fully constructed...
● It will have a “groupName” property set to “Van
Halen”.
● It will have a “singer” property set to “David Lee
Roth”, he'll be 50 years old and 10 years sober.
● 1 line of code, no boilerplate stuff.
● If I want to change those defaults, I don't have to
recompile, I just change a “config” setting.
Inversion Of Control (IOC)
Swapping out one type of Musician for another doesn't require
recompiling code, just change a config:
<class name=”Singer” id=”singerBean2”>
<property name=”name” value=”Sammy Hagar” />
<property name=”yearsSober” value=”15” />
<property name=”age” value=”51” />
</class>
<class name=”RockGroup”>
<property name=”groupName” value=”Van Halen” />
<property name=”singer” ref=”singerBean2” />
</class>
Inversion Of Control (IOC)
Swapping out one type of Musician for another doesn't require
recompiling code, just change a config:
<class name=”Singer” id=”singerBean2”>
<property name=”name” value=”Sammy Hagar” />
<property name=”yearsSober” value=”15” />
<property name=”age” value=”51” />
</class>
<class name=”RockGroup”>
<property name=”groupName” value=”Van Halen” />
<property name=”singer” ref=”singerBean2” />
</class>
Off topic: discussing if Dave is better/worse than Sammy.
Aspect Oriented
Programming (AOP)
Aspect Oriented Programming (AOP)
● AKA “Cross Cutting”.
● Change the “aspect” of how a function is called.
● Say I have a foo() method.
● Any time foo() is called...
● Automatically...
– Call code before or after foo()
– Wrap some sort of code “around” foo()
● e.g. try/catch blocks
● It no longer just does “foo()”.
● Also does whatever you define as an aspect of
calling foo().
Aspect Oriented Programming (AOP)
● Example: drawSalesReport()
● In your AOP library:
<func name=”drawSalesReport”>
<aspect before run=”checkIfLoggedIn” />
<aspect after run=”saveToDebugLogFile” />
</func>
Aspect Oriented Programming (AOP)
● In your code, it USED to look like this:
checkIfLoggedIn();
drawSalesReport( UserID=555,
dtCreated='1/1/2015' );
SaveToDebugLogFile();
What happens NOW is...
DIFramework.runWithAdvice( “drawSalesReport”,
{ UserID=555,
dtCreated='1/1/2015' } );
and that does all 3 things, in correct order.
Aspect Oriented Programming (AOP)
● But wait, there's more!
● Can also wrap “blocks” of code around each
other, not just function calls before/after each
other.
● e.g. try/catch blocks.
Aspect Oriented Programming (AOP)
Say I have a query like so:
<cfquery name=”qryGetUsers”>
SELECT * FROM Users
</cfquery>
In Production, I want that wrapped in a
try/catch, but in QA/Development, I don't. (So I
can see the debug output, etc.)
Aspect Oriented Programming (AOP)
I'd have to set some kind of “flag”:
<cfif isProduction>
<cftry>
<cfquery name=”qryGetUsers”>
SELECT * FROM Users
</cfquery>
<cfcatch> <cflog … /> </cfcatch>
</cftry>
<cfelse>
<cfquery name=”qryGetUsers”>
SELECT * FROM Users
</cfquery>
</cfif>
Duplicate Code!
Remember the DRY rule!
Aspect Oriented Programming (AOP)
● Instead of calling a getUsers() method directly:
● GetUsers();
● In your AOP library:
<advice around functionName=”getUsersWithAdvice”>
<method name=”getUsers” />
</advice>
Aspect Oriented Programming (AOP)
<advice around functionName=”getUsersWithAdvice”>
<method name=”getUsers” />
</advice>
function getUsersWithAdvice( funcToRun ) {
if( isProduction )
{
try{
#funcToRun#();
}
catch{ … }
}else{
#funcToRun#();
}
Aspect Oriented Programming (AOP)
In your code:
DIFramework.runWithAdvice( “getUsers” );
● The if() statement is still there but our
duplicate SQL is gone!
So what's the catch?
● This is maybe a new way of thinking about how
you build your classes.
● Takes some getting used to.
● A little extra “set up” work.
● Naming conventions, or typing some XML.
● Debugging errors can be slower at first.
...but it does make your code more flexible.
Remember...
● You don't have to do this all at once.
● Start with (for example) Bean Management.
● Add other bits as you get comfortable.
● It's not like an MVC framework where the
WHOLE app has to be considered.
● Find 1 tiny spot in your app, add a little DI there.
● Add more in increments, go as you learn.
Also Remember...
● OO Programming is hard.
● It's different than Procedural code.
● Takes getting used to.
● That's NORMAL.
● Nobody learns all this stuff instantly.
● It takes some time.
● (But it is the way most languages are going these
days.)
Other Resources
● Book: Spring In Action (Java)
● Book: Head First Design Patterns
● Framework/1, DI/1 and AOP/1
● ColdSpring documentation
● Good examples, not overwhelming.
● SpringByExample.org
● Java code, but explanation of the general concepts
is pretty good.
● I'm guessing the ColdBox docs are also great
for this too. Those guys like to write!
Questions? Comments?
Ways to reach me...
Email: nolan@southofshasta.com
Twitter: @southofshasta
Blog: southofshasta.com
Thanks!

More Related Content

PDF
Dependency Injection Why is it awesome and Why should I care?
PDF
Dear Kotliners - Java Developers are Humans too
PPTX
Javascript Prototype Visualized
PDF
Prototype
PPT
Java Basics
PDF
Javascript Design Patterns
PDF
JavaScript Patterns
PDF
JavaScript OOPs
Dependency Injection Why is it awesome and Why should I care?
Dear Kotliners - Java Developers are Humans too
Javascript Prototype Visualized
Prototype
Java Basics
Javascript Design Patterns
JavaScript Patterns
JavaScript OOPs

What's hot (20)

PPTX
Js: master prototypes
PPTX
Wintellect - Devscovery - Enterprise JavaScript Development 1 of 2
PDF
Excuse me, sir, do you have a moment to talk about tests in Kotlin
PPT
Object Oriented Programming with Java
PDF
Clean code & design patterns
PDF
Little Did He Know ...
PDF
Design patterns illustrated-2015-03
PPTX
From code to pattern, part one
PPTX
Introduction to OOP(in java) BY Govind Singh
PPT
Oops in PHP
PPT
Metaprogramming With Ruby
PPT
Advanced JavaScript
PDF
Grails Worst Practices
PDF
Object.__class__.__dict__ - python object model and friends - with examples
PPTX
04 Java Language And OOP Part IV
PPTX
Android App code starter
PDF
Java inheritance
PDF
Design patterns illustrated 010PHP
Js: master prototypes
Wintellect - Devscovery - Enterprise JavaScript Development 1 of 2
Excuse me, sir, do you have a moment to talk about tests in Kotlin
Object Oriented Programming with Java
Clean code & design patterns
Little Did He Know ...
Design patterns illustrated-2015-03
From code to pattern, part one
Introduction to OOP(in java) BY Govind Singh
Oops in PHP
Metaprogramming With Ruby
Advanced JavaScript
Grails Worst Practices
Object.__class__.__dict__ - python object model and friends - with examples
04 Java Language And OOP Part IV
Android App code starter
Java inheritance
Design patterns illustrated 010PHP
Ad

Viewers also liked (20)

PDF
This is how we REST
PDF
Powering GIS Operations with ColdFusion
PDF
I am-designer
PDF
The Future of CSS with Web Components
PDF
API Management from the Trenches
PDF
Hidden gems in cf2016
PDF
Relationships are hard
PDF
2015 in tothebox-introtddbdd
PDF
My charts can beat up your charts
PDF
PDF
Mura intergration-slides
PDF
Git sourcecontrolpreso
PDF
Cfobjective fusion reactor sponsor talk
PDF
Understanding bdd and tdd with lego
PDF
Ready? bootstrap. go! (cf objective 14 05-2014)
PPTX
Level up your front-end skills- going beyond cold fusion’s ui tags
PDF
Where is cold fusion headed
PDF
Dev objecttives-2015 auth-auth-fine-grained-slides
PDF
Refactor Large applications with Backbone
PDF
Dependency injectionpreso
This is how we REST
Powering GIS Operations with ColdFusion
I am-designer
The Future of CSS with Web Components
API Management from the Trenches
Hidden gems in cf2016
Relationships are hard
2015 in tothebox-introtddbdd
My charts can beat up your charts
Mura intergration-slides
Git sourcecontrolpreso
Cfobjective fusion reactor sponsor talk
Understanding bdd and tdd with lego
Ready? bootstrap. go! (cf objective 14 05-2014)
Level up your front-end skills- going beyond cold fusion’s ui tags
Where is cold fusion headed
Dev objecttives-2015 auth-auth-fine-grained-slides
Refactor Large applications with Backbone
Dependency injectionpreso
Ad

Similar to Dependency Injection (20)

PDF
Dependency Injection
PDF
Reviewing OOP Design patterns
PDF
HTML5 for the Silverlight Guy
PDF
Intro to OOP
PDF
Oop c sharp_part_1
PPTX
CPP13 - Object Orientation
PPTX
All of Javascript
PDF
Apache Calcite (a tutorial given at BOSS '21)
PPTX
Node.js Patterns for Discerning Developers
PDF
Design Without Types
PPTX
01 - Intro To Using Java
PDF
Mongo learning series
PDF
The Ring programming language version 1.5.4 book - Part 15 of 185
PDF
Lotusphere 2007 AD507 Leveraging the Power of Object Oriented Programming in ...
PPT
Smoothing Your Java with DSLs
PDF
OOPs Interview Questions PDF By ScholarHat
PDF
The Basic Concept Of IOC
PPTX
Solid OOPS
PPTX
OOP, API Design and MVP
PPTX
DevSecCon SG 2018 Fabian Presentation Slides
Dependency Injection
Reviewing OOP Design patterns
HTML5 for the Silverlight Guy
Intro to OOP
Oop c sharp_part_1
CPP13 - Object Orientation
All of Javascript
Apache Calcite (a tutorial given at BOSS '21)
Node.js Patterns for Discerning Developers
Design Without Types
01 - Intro To Using Java
Mongo learning series
The Ring programming language version 1.5.4 book - Part 15 of 185
Lotusphere 2007 AD507 Leveraging the Power of Object Oriented Programming in ...
Smoothing Your Java with DSLs
OOPs Interview Questions PDF By ScholarHat
The Basic Concept Of IOC
Solid OOPS
OOP, API Design and MVP
DevSecCon SG 2018 Fabian Presentation Slides

More from ColdFusionConference (20)

PDF
Api manager preconference
PDF
PDF
Building better SQL Server Databases
PDF
API Economy, Realizing the Business Value of APIs
PDF
Don't just pdf, Smart PDF
PDF
Crafting ColdFusion Applications like an Architect
PDF
Security And Access Control For APIS using CF API Manager
PDF
Monetizing Business Models: ColdFusion and APIS
PDF
Become a Security Rockstar with ColdFusion 2016
PDF
ColdFusion in Transit action
PDF
Developer Insights for Application Upgrade to ColdFusion 2016
PDF
ColdFusion Keynote: Building the Agile Web Since 1995
PDF
Instant ColdFusion with Vagrant
PPT
Restful services with ColdFusion
PDF
Super Fast Application development with Mura CMS
PDF
Build your own secure and real-time dashboard for mobile and web
PDF
Why Everyone else writes bad code
PDF
Securing applications
PDF
Testing automaton
PDF
Rest ful tools for lazy experts
Api manager preconference
Building better SQL Server Databases
API Economy, Realizing the Business Value of APIs
Don't just pdf, Smart PDF
Crafting ColdFusion Applications like an Architect
Security And Access Control For APIS using CF API Manager
Monetizing Business Models: ColdFusion and APIS
Become a Security Rockstar with ColdFusion 2016
ColdFusion in Transit action
Developer Insights for Application Upgrade to ColdFusion 2016
ColdFusion Keynote: Building the Agile Web Since 1995
Instant ColdFusion with Vagrant
Restful services with ColdFusion
Super Fast Application development with Mura CMS
Build your own secure and real-time dashboard for mobile and web
Why Everyone else writes bad code
Securing applications
Testing automaton
Rest ful tools for lazy experts

Recently uploaded (20)

PDF
Encapsulation_ Review paper, used for researhc scholars
PPTX
MYSQL Presentation for SQL database connectivity
PDF
NewMind AI Weekly Chronicles - August'25 Week I
PDF
Encapsulation theory and applications.pdf
PDF
Reach Out and Touch Someone: Haptics and Empathic Computing
PDF
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
PPTX
Big Data Technologies - Introduction.pptx
PDF
Empathic Computing: Creating Shared Understanding
PDF
Machine learning based COVID-19 study performance prediction
PDF
KodekX | Application Modernization Development
PPTX
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
PDF
Dropbox Q2 2025 Financial Results & Investor Presentation
PPTX
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
PDF
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
PDF
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
PPTX
Programs and apps: productivity, graphics, security and other tools
PDF
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
PPTX
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
PDF
Approach and Philosophy of On baking technology
PDF
Network Security Unit 5.pdf for BCA BBA.
Encapsulation_ Review paper, used for researhc scholars
MYSQL Presentation for SQL database connectivity
NewMind AI Weekly Chronicles - August'25 Week I
Encapsulation theory and applications.pdf
Reach Out and Touch Someone: Haptics and Empathic Computing
Peak of Data & AI Encore- AI for Metadata and Smarter Workflows
Big Data Technologies - Introduction.pptx
Empathic Computing: Creating Shared Understanding
Machine learning based COVID-19 study performance prediction
KodekX | Application Modernization Development
ACSFv1EN-58255 AWS Academy Cloud Security Foundations.pptx
Dropbox Q2 2025 Financial Results & Investor Presentation
Effective Security Operations Center (SOC) A Modern, Strategic, and Threat-In...
Optimiser vos workloads AI/ML sur Amazon EC2 et AWS Graviton
7 ChatGPT Prompts to Help You Define Your Ideal Customer Profile.pdf
Programs and apps: productivity, graphics, security and other tools
Architecting across the Boundaries of two Complex Domains - Healthcare & Tech...
KOM of Painting work and Equipment Insulation REV00 update 25-dec.pptx
Approach and Philosophy of On baking technology
Network Security Unit 5.pdf for BCA BBA.

Dependency Injection

  • 1. Dependency Injection: Why is it awesome and why should I care? Nolan Erck
  • 2. About Me ● Consultant (southofshasta.com) ● Software Development, On-site Training, Design ● Using ColdFusion since 1999 (4.x) ● Other stuff: C++, Java, jQuery, PHP, .NET, HTML5, Android, you get the idea... ● Manager of SacInteractive ● Reformed Video Game Developer (Grim Fandango, SimPark, StarWars Rogue Squadron, etc). ● Music Junkie
  • 6. Today's Agenda ● What is Dependency Injection? ● When/why do I want it in my projects? ● Intro to Bean Management ● Intro to Aspect Oriented Programming (AOP) ● Intro to Inversion of Control (IOC) ● Other info ● Questions
  • 7. Prerequisites ● Have some experience building classes and objects. ● Don't need to be an expert. ● Don't need to have used an MVC framework. ● DI frameworks can be totally separate. ● And 1 more thing you need to know...
  • 8. Prerequisites ● Know that Object Oriented Programming is hard. ● And some of it is confusing at first. ● And that's NORMAL.
  • 10. What is Dependency Injection? ● A “design pattern” ● $6 phrase for “a way to organize your classes so they work together in a flexible way”. ● Like a for() loop, if(), array[] – Reusable technique, based around objects. ● There are lots of design patterns: – Dependency Injection is 1 design pattern – Inversion of Control (IOC), Aspect Oriented Programming (AOP) and Bean Management are all “variations on that theme”. – There are lots of others too.
  • 11. What is Dependency Injection? ● It's not platform specific. ● Available for ColdFusion, Java, .NET, JavaScript, etc. ● For today's preso: ● Using mostly pseudocode. ● Some keywords will change. ● All the concepts work the same across libraries and languages.
  • 12. Why / When Do I Want D/I In My Projects? ● Short answer: When you have lots of classes that talk to each other, want to keep code organized, and make it easy to swap different “types” of objects in/out of your application.
  • 13. Why / When Do I Want D/I In My Projects? ● Short answer: When you have lots of classes that talk to each other, want to keep code organized, and make it easy to swap different “types” of objects in/out of your application. ● Longer answer: That's what the rest of the slides are for...
  • 14. Does this mean... ● I have to rebuild my entire app to use D/I? ● No. But you might get more benefits if you make a few changes to legacy code along the way. ● I have to learn a new way to code all my classes? ● No. You can leave everything as-is. – The nice thing about D/I is you can use it or not use it. If you want to write code the “old way” in part of your app, there's nothing stopping you from doing so. It will all still work as-is. ● Neat huh? Let's learn a bit more, shall we?
  • 16. What's a Bean? A “thing” your D/I framework knows about. class User{ … } class DateUtils {…} In your DI framework: bean id=”myUser” class=”User” bean id=”myDateUtils” class=”DateUtils” (Exact syntax varies between DI libraries.)
  • 17. Bean Management class A { public class A() {...} } class B{ public class B(A a) { … } } class C { public class C(B b) { … } } class D{ public class D(C c) {...} } So if I -JUST- want a D object made...
  • 18. Bean Management I have to do all this... A a = new A(); B b = new B( a ); C c = new C( b ); D d = new D( c ); 4 lines of code. The first 3 are “boilerplate” to create the variables I need to make a D. Multiply that out over all the objects in your app... = a LOT of boilerplate code! Another way to say it: “D depends on A, B and C being made first”.
  • 19. Bean Management With a D/I library that does Bean Management, you'd write something like this instead... D d = ColdSpring.getBean( “D” ); 4 lines of code just became 1. And no more boilerplate stuff! You tell your D/I framework “I need a D. Go find out what D depends on, make those as needed, and hand me back D when you're done.” (“ColdSpring” is a placeholder here for any D/I framework. They all work about the same.)
  • 20. Bean Management ● Quasi Real World Example. ● Mailing department wide messages. ● Mail Service CFC ● Needs a Department CFC to know which Department is being emailed. ● Department needs a Department DAO for it's SQL stuff. ● And a SecurityLogin CFC to make sure it's validated/logged in/whatever.
  • 21. Bean Management ● Old Way mySecLogin = CreateObject( “component”, “SecurityLogin”); myDeptDAO = CreateObject(“component”,“DepartmentDAO”); dept = CreateObject( “component”, “Department” ); dept.init( mySecLogin, myDeptDAO ); mailSvc = CreateObject( “component”, “MailService” ); mailSvc.init( dept ); mailSvc.sendEmail();
  • 22. Bean Management ● New Way ColdSpring.getBean( “mailService” ).sendMail();
  • 23. Bean Management ● New Way ColdSpring.getBean( “mailService” ).sendMail(); Yes, 1 line of code. Yes, it is THAT easy. (I'm over simplifying a little.)
  • 24. Bean Management ● So how does the D/I framework “know” that I need an A, B and C to make a D object? ● Varies a little from framework to framework. ● Configuration based: XML file that “describes” the relationship between the objects. ● (ColdSpring, Spring) – Nice for, say, white-box testing w/ hands-on QA team. ● Convention based: ● Works automatically by which folders you store classes in, and how the classes are named. ● DI/1, WireBox ● Just pick one and try it out, they all do the same core “things”.
  • 26. Inversion of Control (IOC) ● Fancy term for “flipping” some code around from the “traditional” or “normal” way you'd build objects. ● Instead of building an Employee object, then a Department object, then putting the Employee IN the Department. ● You say “get me a fully populated/constructed Department”. ● Magic happens, automatically building the Employee object for you.
  • 27. Inversion Of Control (IOC) class RockGroup { private String groupName; public String getGroupName(){ return groupName; } public void setGroupName(String name) { this.groupName = name; } } No Constructor. “groupName” is private. So we have to call the setter to initialize the variable with something.
  • 28. Inversion Of Control (IOC) With regular code, we'd do this: String myBandName = “depeche mode”; RockGroup rg = new RockGroup(); rg.setGroupName( myBandName ); That works but... Every time I want to provide a different default value, I have to change code, and recompile.
  • 29. Inversion Of Control (IOC) What if we could provide that default value in a “config file”, outside of code? And whenever we create a RockGroup object, it automatically gets a default value for groupName passed in at that instant? You can!
  • 30. Inversion Of Control (IOC) Using a D/I framework, you can have a “config” that notes default values for your classes: <class name=”RockGroup”> <property name=”groupName” value=”Depeche Mode”/> </class> rg = ColdSpring.getBean( “RockGroup” ) ...any time I make a RockGroup, it will automatically initialize the “groupName” variable to the default value I provided. No extra lines of code. And changing this default is now done in a config file. No recompiling code to change it!
  • 31. Inversion Of Control (IOC) What about classes inside of other classes? ● AKA “Composition”, the “has a” relationship. ● Kind of the same thing...
  • 32. Inversion Of Control (IOC) class RockGroup{ private String groupName; public String getGroupName() { … } public void setGroupName( String name ) {…} private Musician singer; public Musician getSinger() { … } public void setSinger( Musician m ) {…} } class Musician{ private String name; private int yearsSober; private int age; public String getName() { return name; } public void setName(String n) { this.name = n; } public int getYearsSober() { … } public void setYearsSober(int y) { … } public void setAge( int a ){...} public int getAge(){ return age; } }
  • 33. Inversion of Control (IOC) With straight code... Musician m = new Musician(); m.name = “David Lee Roth”; m.age = 50; m.yearsSober = 10; RockGroup rg = new RockGroup(); rg.setGroupName( “Van Halen” ); rg.setSinger( m );
  • 34. Inversion of Control (IOC) With D/I... RockGroup rg = Spring.getBean(“RockGroup”);
  • 35. Inversion Of Control (IOC) The Musician class has a String property, that gets initialized just like the String property in RockGroup. Ditto for the “int” properties, etc: Spring.getBean( “Musician” ); – “name” will always be whatever is in my config for the Musician class. <class name=”Musician”> <property name=”name” value=”David Lee Roth” /> <property name=”age” value=”50” /> <property name=”yearsSober” value=”10” /> </class>
  • 36. Inversion Of Control (IOC) You can also refer to other classes in the config, and “inject” them into each other, just like we “injected” the String and int into Musician: <class name=”Singer” id=”mySingerBean”> <property name=”name” value=”David Lee Roth” /> <property name=”yearsSober” value=”10” /> <property name=”age” value=”50” /> </class> <class name=”RockGroup”> <property name=”groupName” value=”Van Halen” /> <property name=”singer” ref=”mySingerBean” /> </class>
  • 37. Inversion Of Control (IOC) So now when I do this... rg = DIFramework.getBean( “RockGroup” ); ● rg will be fully constructed... ● It will have a “groupName” property set to “Van Halen”. ● It will have a “singer” property set to “David Lee Roth”, he'll be 50 years old and 10 years sober. ● 1 line of code, no boilerplate stuff. ● If I want to change those defaults, I don't have to recompile, I just change a “config” setting.
  • 38. Inversion Of Control (IOC) Swapping out one type of Musician for another doesn't require recompiling code, just change a config: <class name=”Singer” id=”singerBean2”> <property name=”name” value=”Sammy Hagar” /> <property name=”yearsSober” value=”15” /> <property name=”age” value=”51” /> </class> <class name=”RockGroup”> <property name=”groupName” value=”Van Halen” /> <property name=”singer” ref=”singerBean2” /> </class>
  • 39. Inversion Of Control (IOC) Swapping out one type of Musician for another doesn't require recompiling code, just change a config: <class name=”Singer” id=”singerBean2”> <property name=”name” value=”Sammy Hagar” /> <property name=”yearsSober” value=”15” /> <property name=”age” value=”51” /> </class> <class name=”RockGroup”> <property name=”groupName” value=”Van Halen” /> <property name=”singer” ref=”singerBean2” /> </class> Off topic: discussing if Dave is better/worse than Sammy.
  • 41. Aspect Oriented Programming (AOP) ● AKA “Cross Cutting”. ● Change the “aspect” of how a function is called. ● Say I have a foo() method. ● Any time foo() is called... ● Automatically... – Call code before or after foo() – Wrap some sort of code “around” foo() ● e.g. try/catch blocks ● It no longer just does “foo()”. ● Also does whatever you define as an aspect of calling foo().
  • 42. Aspect Oriented Programming (AOP) ● Example: drawSalesReport() ● In your AOP library: <func name=”drawSalesReport”> <aspect before run=”checkIfLoggedIn” /> <aspect after run=”saveToDebugLogFile” /> </func>
  • 43. Aspect Oriented Programming (AOP) ● In your code, it USED to look like this: checkIfLoggedIn(); drawSalesReport( UserID=555, dtCreated='1/1/2015' ); SaveToDebugLogFile(); What happens NOW is... DIFramework.runWithAdvice( “drawSalesReport”, { UserID=555, dtCreated='1/1/2015' } ); and that does all 3 things, in correct order.
  • 44. Aspect Oriented Programming (AOP) ● But wait, there's more! ● Can also wrap “blocks” of code around each other, not just function calls before/after each other. ● e.g. try/catch blocks.
  • 45. Aspect Oriented Programming (AOP) Say I have a query like so: <cfquery name=”qryGetUsers”> SELECT * FROM Users </cfquery> In Production, I want that wrapped in a try/catch, but in QA/Development, I don't. (So I can see the debug output, etc.)
  • 46. Aspect Oriented Programming (AOP) I'd have to set some kind of “flag”: <cfif isProduction> <cftry> <cfquery name=”qryGetUsers”> SELECT * FROM Users </cfquery> <cfcatch> <cflog … /> </cfcatch> </cftry> <cfelse> <cfquery name=”qryGetUsers”> SELECT * FROM Users </cfquery> </cfif> Duplicate Code! Remember the DRY rule!
  • 47. Aspect Oriented Programming (AOP) ● Instead of calling a getUsers() method directly: ● GetUsers(); ● In your AOP library: <advice around functionName=”getUsersWithAdvice”> <method name=”getUsers” /> </advice>
  • 48. Aspect Oriented Programming (AOP) <advice around functionName=”getUsersWithAdvice”> <method name=”getUsers” /> </advice> function getUsersWithAdvice( funcToRun ) { if( isProduction ) { try{ #funcToRun#(); } catch{ … } }else{ #funcToRun#(); }
  • 49. Aspect Oriented Programming (AOP) In your code: DIFramework.runWithAdvice( “getUsers” ); ● The if() statement is still there but our duplicate SQL is gone!
  • 50. So what's the catch? ● This is maybe a new way of thinking about how you build your classes. ● Takes some getting used to. ● A little extra “set up” work. ● Naming conventions, or typing some XML. ● Debugging errors can be slower at first. ...but it does make your code more flexible.
  • 51. Remember... ● You don't have to do this all at once. ● Start with (for example) Bean Management. ● Add other bits as you get comfortable. ● It's not like an MVC framework where the WHOLE app has to be considered. ● Find 1 tiny spot in your app, add a little DI there. ● Add more in increments, go as you learn.
  • 52. Also Remember... ● OO Programming is hard. ● It's different than Procedural code. ● Takes getting used to. ● That's NORMAL. ● Nobody learns all this stuff instantly. ● It takes some time. ● (But it is the way most languages are going these days.)
  • 53. Other Resources ● Book: Spring In Action (Java) ● Book: Head First Design Patterns ● Framework/1, DI/1 and AOP/1 ● ColdSpring documentation ● Good examples, not overwhelming. ● SpringByExample.org ● Java code, but explanation of the general concepts is pretty good. ● I'm guessing the ColdBox docs are also great for this too. Those guys like to write!
  • 54. Questions? Comments? Ways to reach me... Email: nolan@southofshasta.com Twitter: @southofshasta Blog: southofshasta.com Thanks!