SlideShare a Scribd company logo
1 of 57
What is this DI and AOP stuff anyway...
Friday, June 7, 13
About Me
Currently BBC Sport (Freelancer)
Lived in Japan for 15 years - love sushi
Love frameworks - not just PHP ones
Involved in Lithium and BEAR.Sunday projects
Richard McIntyre - @mackstar
Friday, June 7, 13
Dependency Injection
Friday, June 7, 13
Most Basic Example - Problem
class Mailer
{
private $transport;
public function __construct()
{
$this->transport = 'sendmail';
}
// ...
}
Friday, June 7, 13
Expensive
new Zend_Config_Ini($path, ENV);
Friday, June 7, 13
Easily becomes an inheritance mess
Sport_Lib_Builder_GenericStatsAbstract
Sport_Lib_Builder_GenericStats_Cricket_Table
Sport_Lib_Builder_GenericStats_Cricket_NarrowTable
Sport_Lib_Builder_GenericStats_CricketAbstract
Sport_Lib_API_GenericStats_Cricket
Sport_Lib_API_GenericStatsAbstract
Sport_Lib_Service_SportsData_Cricket
Sport_Lib_Service_SportsData
Sport_Lib_ServiceAbstract
Friday, June 7, 13
DI for a 5 year old
When you go and get things out of the refrigerator for yourself, you can
cause problems. You might leave the door open, you might get something
Mommy or Daddy doesn't want you to have. You might even be looking
for something we don't even have or which has expired.
What you should be doing is stating a need, "I need something to drink
with lunch," and then we will make sure you have something when you
sit down to eat.
Friday, June 7, 13
Something like this...
Application needs Foo, which needs Bar, which needs Bim, so:
Application creates Bim
Application creates Bar and gives it Bim
Application creates Foo and gives it Bar
Application calls Foo
Foo calls Bar
Bar does something
Friday, June 7, 13
The Service Container
Dependency Injection Round 1
Friday, June 7, 13
class Mailer
{
private $transport;
public function __construct($transport)
{
$this->transport = $transport;
}
// ...
}
Symfony2 Example
Friday, June 7, 13
class Mailer
{
private $transport;
public function __construct($transport)
{
$this->transport = $transport;
}
// ...
}
use SymfonyComponentDependencyInjectionContainerBuilder;
$container = new ContainerBuilder();
$container->register('mailer', 'Mailer');
Symfony2 Example
Friday, June 7, 13
class Mailer
{
private $transport;
public function __construct($transport)
{
$this->transport = $transport;
}
// ...
}
use SymfonyComponentDependencyInjectionContainerBuilder;
$container = new ContainerBuilder();
$container->register('mailer', 'Mailer');
use SymfonyComponentDependencyInjectionContainerBuilder;
$container = new ContainerBuilder();
$container
->register('mailer', 'Mailer')
->addArgument('sendmail');
Symfony2 Example
Friday, June 7, 13
class NewsletterManager
{
private $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
// ...
}
Friday, June 7, 13
class NewsletterManager
{
private $mailer;
public function __construct(Mailer $mailer)
{
$this->mailer = $mailer;
}
// ...
}
use SymfonyComponentDependencyInjectionContainerBuilder;
use SymfonyComponentDependencyInjectionReference;
$container = new ContainerBuilder();
$container->setParameter('mailer.transport', 'sendmail');
$container
->register('mailer', 'Mailer')
->addArgument('%mailer.transport%');
$container
->register('newsletter_manager', 'NewsletterManager')
->addArgument(new Reference('mailer'));
Friday, June 7, 13
use SymfonyComponentDependencyInjectionContainerBuilder;
$container = new ContainerBuilder();
$newsletterManager = $container->get('newsletter_manager');
Friday, June 7, 13
Inversion Of Control
Pattern
The control of the dependencies is inversed from one
being called to the one calling.
Friday, June 7, 13
Container
Newsletter Manager
Mailer
transport = sendmail
Friday, June 7, 13
Container
Newsletter Manager
Mailer
# src/Acme/HelloBundle/Resources/config/
services.yml
parameters:
# ...
mailer.transport: sendmail
services:
mailer:
class: Mailer
arguments: [%mailer.transport%]
newsletter_manager:
class: NewsletterManager
calls:
- [ setMailer, [ @mailer ] ]
transport = sendmail
Friday, June 7, 13
Decoupled Code
Friday, June 7, 13
Tips
Test first in isolation
Don’t need to wire together to test (Eg Environment etc)
integration tests are expensive.
When you do wire together with test/mock classes as needed
Duck Type your code / Use interfaces
Friday, June 7, 13
Friday, June 7, 13
$container = new Pimple();
// define some parameters
$container['cookie_name'] = 'SESSION_ID';
$container['session_storage_class'] = 'SessionStorage';
Friday, June 7, 13
$container = new Pimple();
// define some parameters
$container['cookie_name'] = 'SESSION_ID';
$container['session_storage_class'] = 'SessionStorage';
// define some objects
$container['session_storage'] = function ($c) {
return new $c['session_storage_class']($c['cookie_name']);
};
$container['session'] = function ($c) {
return new Session($c['session_storage']);
};
Friday, June 7, 13
Clever DI with Bindings
Friday, June 7, 13
Laravel 4 example
class MyConcreteClass implements MyInterface
{
Friday, June 7, 13
Laravel 4 example
class MyConcreteClass implements MyInterface
{
class MyClass
{
public function __construct(MyInterface $my_injection)
{
$this->my_injection = $my_injection;
}
}
App::bind('MyInterface', 'MyConcreteClass');
Friday, June 7, 13
Cleverer DI with Injection
Points & Bindings
Friday, June 7, 13
Google Guice
Guice alleviates the need for factories and the use of ‘new’ in
your ‘Java’a code
Think of Guice's @Inject as the new new. You will still need
to write factories in some cases, but your code will not
depend directly on them. Your code will be easier to change,
unit test and reuse in other contexts.
Ray.DI
Friday, June 7, 13
interface MailerInterface {}
PHP Google Guice Clone
Ray.DI
Friday, June 7, 13
class Mailer implements MailerInterface
{
private $transport;
/**
* @Inject
* @Named("transport_type")
*/
public function __construct($transport)
{
$this->transport = $transport;
}
}
interface MailerInterface {}
PHP Google Guice Clone
Ray.DI
Friday, June 7, 13
class Mailer implements MailerInterface
{
private $transport;
/**
* @Inject
* @Named("transport_type")
*/
public function __construct($transport)
{
$this->transport = $transport;
}
}
interface MailerInterface {}
class NewsletterManager
{
public $mailer;
/**
* @Inject
*/
public function __construct(MailerInterface $mailer)
{
$this->mailer = $mailer;
}
}
PHP Google Guice Clone
Ray.DI
Friday, June 7, 13
class NewsletterModule extends AbstractModule
{
protected function configure()
{
$this->bind()->annotatedWith('transport_type')->toInstance('sendmail');
$this->bind('MailerInterface')->to('Mailer');
}
}
Friday, June 7, 13
class NewsletterModule extends AbstractModule
{
protected function configure()
{
$this->bind()->annotatedWith('transport_type')->toInstance('sendmail');
$this->bind('MailerInterface')->to('Mailer');
}
} $di = Injector::create([new NewsletterModule]);
$newsletterManager = $di->getInstance('NewsletterManager');
Friday, June 7, 13
class NewsletterModule extends AbstractModule
{
protected function configure()
{
$this->bind()->annotatedWith('transport_type')->toInstance('sendmail');
$this->bind('MailerInterface')->to('Mailer');
}
} $di = Injector::create([new NewsletterModule]);
$newsletterManager = $di->getInstance('NewsletterManager');
$works = ($newsletterManager->mailer instanceof MailerInterface);
Friday, June 7, 13
Problems?/Gochas
1. Overly abstracted code
2. Easy to go crazy with it
3. Too many factory classes
4. Easy to loose what data is where
5. Container is like super global variable
Friday, June 7, 13
Many other
implementations
Friday, June 7, 13
Aspect Orientated
Programming
Friday, June 7, 13
The Problem
function addPost() {
$log->writeToLog("Entering addPost");
// Business Logic
$log->writeToLog("Leaving addPost");
}
Friday, June 7, 13
The Problem
function addPost() {
$log->writeToLog("Entering addPost");
// Business Logic
$log->writeToLog("Leaving addPost");
}
function addPost() {
$authentication->validateAuthentication($user);
$authorization->validateAccess($user);
// Business Logic
}
Friday, June 7, 13
Core Class Aspect Class
AOP Framework
Proxy Class
Continue Process
Friday, June 7, 13
Lithium Example -Logging in your model
namespace appmodels;
use lithiumutilcollectionFilters;
use lithiumutilLogger;
Filters::apply('appmodelsPost', 'save', function($self, $params, $chain) {
Logger::write('info', $params['data']['title']);
return $chain->next($self, $params, $chain);
});
Friday, June 7, 13
Dispatcher::applyFilter('run', function($self, $params, $chain) {
$key = md5($params['request']->url);
if($cache = Cache::read('default', $key)) {
return $cache;
}
$result = $chain->next($self, $params, $chain);
Cache::write('default', $key, $result, '+1 day');
return $result;
});
Lithium Example -Caching
Friday, June 7, 13
Friday, June 7, 13
Find
Friday, June 7, 13
Cache
Find
Friday, June 7, 13
Log
Cache
Find
Friday, June 7, 13
Log
Cache
Find
Friday, June 7, 13
Log
Cache
Find
Friday, June 7, 13
Log
Cache
Find
Friday, June 7, 13
Ray.AOP
Guice AOP Clone
Friday, June 7, 13
/**
* NotOnWeekends
*
* @Annotation
* @Target("METHOD")
*/
final class NotOnWeekends
{
}
Create Annotation
Create Real Class - Billing service
Friday, June 7, 13
/**
* NotOnWeekends
*
* @Annotation
* @Target("METHOD")
*/
final class NotOnWeekends
{
}
Create Annotation
class RealBillingService
{
/**
* @NotOnWeekends
*/
chargeOrder(PizzaOrder $order, CreditCard $creditCard)
{
Create Real Class - Billing service
Friday, June 7, 13
class WeekendBlocker implements MethodInterceptor
{
public function invoke(MethodInvocation $invocation)
{
$today = getdate();
if ($today['weekday'][0] === 'S') {
throw new RuntimeException(
$invocation->getMethod()->getName() . " not allowed on weekends!"
);
}
return $invocation->proceed();
}
}
Interception Logic
Friday, June 7, 13
$bind = new Bind;
$matcher = new Matcher(new Reader);
$interceptors = [new WeekendBlocker];
$pointcut = new Pointcut(
$matcher->any(),
$matcher->annotatedWith('RayAopSampleAnnotationNotOnWeekends'),
$interceptors
);
$bind->bind('RayAopSampleAnnotationRealBillingService', [$pointcut]);
$billing = new Weaver(new RealBillingService, $bind);
try {
echo $billing->chargeOrder();
} catch (RuntimeException $e) {
echo $e->getMessage() . "n";
exit(1);
}
Binding on Annotation
Friday, June 7, 13
$bind = new Bind;
$bind->bindInterceptors('chargeOrder', [new WeekendBlocker]);
$billingService = new Weaver(new RealBillingService, $bind);
try {
echo $billingService->chargeOrder();
} catch (RuntimeException $e) {
echo $e->getMessage() . "n";
exit(1);
}
Explicit Method Binding
Friday, June 7, 13
Gochas
Friday, June 7, 13
BEAR.Sunday
Friday, June 7, 13

More Related Content

What's hot

ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf Conference
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
Alexei Gorobets
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
Wildan Maulana
 
Introduction to javascript and yoolkui
Introduction to javascript and yoolkuiIntroduction to javascript and yoolkui
Introduction to javascript and yoolkui
Khou Suylong
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
旻琦 潘
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
Ignacio Martín
 

What's hot (20)

ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
ZFConf 2010: Zend Framework & MVC, Model Implementation (Part 2, Dependency I...
 
PyFoursquare: Python Library for Foursquare
PyFoursquare: Python Library for FoursquarePyFoursquare: Python Library for Foursquare
PyFoursquare: Python Library for Foursquare
 
Js: master prototypes
Js: master prototypesJs: master prototypes
Js: master prototypes
 
Dependency injection in Drupal 8
Dependency injection in Drupal 8Dependency injection in Drupal 8
Dependency injection in Drupal 8
 
Object Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOPObject Oriented Programming with PHP 5 - More OOP
Object Oriented Programming with PHP 5 - More OOP
 
Clean code in JavaScript
Clean code in JavaScriptClean code in JavaScript
Clean code in JavaScript
 
Prototype
PrototypePrototype
Prototype
 
Introduction to javascript and yoolkui
Introduction to javascript and yoolkuiIntroduction to javascript and yoolkui
Introduction to javascript and yoolkui
 
Advanced javascript
Advanced javascriptAdvanced javascript
Advanced javascript
 
The Beauty and the Beast
The Beauty and the BeastThe Beauty and the Beast
The Beauty and the Beast
 
Java Script Best Practices
Java Script Best PracticesJava Script Best Practices
Java Script Best Practices
 
Oops in php
Oops in phpOops in php
Oops in php
 
Php unit the-mostunknownparts
Php unit the-mostunknownpartsPhp unit the-mostunknownparts
Php unit the-mostunknownparts
 
Bubbles & Trees with jQuery
Bubbles & Trees with jQueryBubbles & Trees with jQuery
Bubbles & Trees with jQuery
 
A tour on ruby and friends
A tour on ruby and friendsA tour on ruby and friends
A tour on ruby and friends
 
PHP Classes and OOPS Concept
PHP Classes and OOPS ConceptPHP Classes and OOPS Concept
PHP Classes and OOPS Concept
 
Javascript Experiment
Javascript ExperimentJavascript Experiment
Javascript Experiment
 
The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09The Beauty And The Beast Php N W09
The Beauty And The Beast Php N W09
 
Symfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worldsSymfony & Javascript. Combining the best of two worlds
Symfony & Javascript. Combining the best of two worlds
 
Basic Oops concept of PHP
Basic Oops concept of PHPBasic Oops concept of PHP
Basic Oops concept of PHP
 

Viewers also liked

Primitive life photos
Primitive life photosPrimitive life photos
Primitive life photos
kwiley0019
 
Microsoft word thi bd đh hoa-485
Microsoft word   thi bd đh hoa-485Microsoft word   thi bd đh hoa-485
Microsoft word thi bd đh hoa-485
vjt_chjen
 
Cmt 3321 intercom presentation 3 week 14
Cmt 3321 intercom presentation 3 week 14Cmt 3321 intercom presentation 3 week 14
Cmt 3321 intercom presentation 3 week 14
amitpac7
 
Hoahoctuoitre1
Hoahoctuoitre1Hoahoctuoitre1
Hoahoctuoitre1
vjt_chjen
 
The molecular times
The molecular timesThe molecular times
The molecular times
jonyfive5
 
2c; photosynthesis
2c; photosynthesis2c; photosynthesis
2c; photosynthesis
kwiley0019
 
An amazing man
An amazing manAn amazing man
An amazing man
AAR VEE
 
Hello,my nameis.lawlor
Hello,my nameis.lawlorHello,my nameis.lawlor
Hello,my nameis.lawlor
tnlawlor
 
апкс 2011 04_verilog
апкс 2011 04_verilogапкс 2011 04_verilog
апкс 2011 04_verilog
Irina Hahanova
 

Viewers also liked (20)

Primitive life photos
Primitive life photosPrimitive life photos
Primitive life photos
 
Clean out the lungs
Clean out the lungsClean out the lungs
Clean out the lungs
 
Cacsodovoco
CacsodovocoCacsodovoco
Cacsodovoco
 
Microsoft word thi bd đh hoa-485
Microsoft word   thi bd đh hoa-485Microsoft word   thi bd đh hoa-485
Microsoft word thi bd đh hoa-485
 
Soil Management, Site Selection. Soil Fertility
Soil Management, Site Selection. Soil FertilitySoil Management, Site Selection. Soil Fertility
Soil Management, Site Selection. Soil Fertility
 
Cmt 3321 intercom presentation 3 week 14
Cmt 3321 intercom presentation 3 week 14Cmt 3321 intercom presentation 3 week 14
Cmt 3321 intercom presentation 3 week 14
 
Hoahoctuoitre1
Hoahoctuoitre1Hoahoctuoitre1
Hoahoctuoitre1
 
world beneath the waves
world beneath the wavesworld beneath the waves
world beneath the waves
 
Howard Guardian
Howard GuardianHoward Guardian
Howard Guardian
 
The molecular times
The molecular timesThe molecular times
The molecular times
 
Yntercaran
YntercaranYntercaran
Yntercaran
 
Change Management
Change ManagementChange Management
Change Management
 
Samuel slide
Samuel slideSamuel slide
Samuel slide
 
2c; photosynthesis
2c; photosynthesis2c; photosynthesis
2c; photosynthesis
 
2
22
2
 
An amazing man
An amazing manAn amazing man
An amazing man
 
Global classroom project 2012 2013
Global classroom project 2012 2013Global classroom project 2012 2013
Global classroom project 2012 2013
 
Hello,my nameis.lawlor
Hello,my nameis.lawlorHello,my nameis.lawlor
Hello,my nameis.lawlor
 
апкс 2011 04_verilog
апкс 2011 04_verilogапкс 2011 04_verilog
апкс 2011 04_verilog
 
001
001001
001
 

Similar to What is this DI and AOP stuff anyway...

Magento Attributes - Fresh View
Magento Attributes - Fresh ViewMagento Attributes - Fresh View
Magento Attributes - Fresh View
Alex Gotgelf
 
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileOpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
Dierk König
 
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with MagentoMagento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
MagentoImagine
 

Similar to What is this DI and AOP stuff anyway... (20)

Magento Attributes - Fresh View
Magento Attributes - Fresh ViewMagento Attributes - Fresh View
Magento Attributes - Fresh View
 
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013Drupal 8 configuration system for coders and site builders - Drupalaton 2013
Drupal 8 configuration system for coders and site builders - Drupalaton 2013
 
Keeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro frameworkKeeping it small - Getting to know the Slim PHP micro framework
Keeping it small - Getting to know the Slim PHP micro framework
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...How to write better code: in-depth best practices for writing readable, simpl...
How to write better code: in-depth best practices for writing readable, simpl...
 
Unittests für Dummies
Unittests für DummiesUnittests für Dummies
Unittests für Dummies
 
Intro to Ember.js
Intro to Ember.jsIntro to Ember.js
Intro to Ember.js
 
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
4Developers 2015: Be pragmatic, be SOLID - Krzysztof Menżyk
 
Be pragmatic, be SOLID
Be pragmatic, be SOLIDBe pragmatic, be SOLID
Be pragmatic, be SOLID
 
Writing JavaScript that doesn't suck
Writing JavaScript that doesn't suckWriting JavaScript that doesn't suck
Writing JavaScript that doesn't suck
 
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and MobileOpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
OpenDolphin: Enterprise Apps for collaboration on Desktop, Web, and Mobile
 
Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long Multi Client Development with Spring - Josh Long
Multi Client Development with Spring - Josh Long
 
Magento Imagine eCommerce Conference - February 2011 - Unit Testing with Magento
Magento Imagine eCommerce Conference - February 2011 - Unit Testing with MagentoMagento Imagine eCommerce Conference - February 2011 - Unit Testing with Magento
Magento Imagine eCommerce Conference - February 2011 - Unit Testing with Magento
 
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with MagentoMagento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
Magento's Imagine eCommerce Conference 2011 - Unit Testing with Magento
 
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
Be pragmatic, be SOLID (at Boiling Frogs, Wrocław)
 
Pragmatic JavaScript
Pragmatic JavaScriptPragmatic JavaScript
Pragmatic JavaScript
 
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
Drupal 8 configuration system for coders and site builders - DrupalCamp Balti...
 
Lone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New AngleLone StarPHP 2013 - Building Web Apps from a New Angle
Lone StarPHP 2013 - Building Web Apps from a New Angle
 
Ember and containers
Ember and containersEmber and containers
Ember and containers
 
Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...Singletons in PHP - Why they are bad and how you can eliminate them from your...
Singletons in PHP - Why they are bad and how you can eliminate them from your...
 

More from Richard McIntyre (9)

Why Message Driven?
Why Message Driven?Why Message Driven?
Why Message Driven?
 
Current state-of-php
Current state-of-phpCurrent state-of-php
Current state-of-php
 
Spout
SpoutSpout
Spout
 
Spout
SpoutSpout
Spout
 
Semantic BDD with ShouldIT?
Semantic BDD with ShouldIT?Semantic BDD with ShouldIT?
Semantic BDD with ShouldIT?
 
Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
Spout - Building a RESTful web app with Angular.js and BEAR.SundaySpout - Building a RESTful web app with Angular.js and BEAR.Sunday
Spout - Building a RESTful web app with Angular.js and BEAR.Sunday
 
Lithium Best
Lithium Best Lithium Best
Lithium Best
 
Using Backbone with CakePHP
Using Backbone with CakePHPUsing Backbone with CakePHP
Using Backbone with CakePHP
 
Future of PHP
Future of PHPFuture of PHP
Future of PHP
 

Recently uploaded

IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
Enterprise Knowledge
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
Joaquim Jorge
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
vu2urc
 

Recently uploaded (20)

TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Boost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdfBoost Fertility New Invention Ups Success Rates.pdf
Boost Fertility New Invention Ups Success Rates.pdf
 
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdfUnderstanding Discord NSFW Servers A Guide for Responsible Users.pdf
Understanding Discord NSFW Servers A Guide for Responsible Users.pdf
 
A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)A Domino Admins Adventures (Engage 2024)
A Domino Admins Adventures (Engage 2024)
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)Powerful Google developer tools for immediate impact! (2023-24 C)
Powerful Google developer tools for immediate impact! (2023-24 C)
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
Strategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a FresherStrategies for Landing an Oracle DBA Job as a Fresher
Strategies for Landing an Oracle DBA Job as a Fresher
 
Artificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and MythsArtificial Intelligence: Facts and Myths
Artificial Intelligence: Facts and Myths
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot TakeoffStrategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
Strategize a Smooth Tenant-to-tenant Migration and Copilot Takeoff
 
Boost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivityBoost PC performance: How more available memory can improve productivity
Boost PC performance: How more available memory can improve productivity
 
Histor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slideHistor y of HAM Radio presentation slide
Histor y of HAM Radio presentation slide
 
GenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdfGenAI Risks & Security Meetup 01052024.pdf
GenAI Risks & Security Meetup 01052024.pdf
 
🐬 The future of MySQL is Postgres 🐘
🐬  The future of MySQL is Postgres   🐘🐬  The future of MySQL is Postgres   🐘
🐬 The future of MySQL is Postgres 🐘
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 

What is this DI and AOP stuff anyway...

  • 1. What is this DI and AOP stuff anyway... Friday, June 7, 13
  • 2. About Me Currently BBC Sport (Freelancer) Lived in Japan for 15 years - love sushi Love frameworks - not just PHP ones Involved in Lithium and BEAR.Sunday projects Richard McIntyre - @mackstar Friday, June 7, 13
  • 4. Most Basic Example - Problem class Mailer { private $transport; public function __construct() { $this->transport = 'sendmail'; } // ... } Friday, June 7, 13
  • 6. Easily becomes an inheritance mess Sport_Lib_Builder_GenericStatsAbstract Sport_Lib_Builder_GenericStats_Cricket_Table Sport_Lib_Builder_GenericStats_Cricket_NarrowTable Sport_Lib_Builder_GenericStats_CricketAbstract Sport_Lib_API_GenericStats_Cricket Sport_Lib_API_GenericStatsAbstract Sport_Lib_Service_SportsData_Cricket Sport_Lib_Service_SportsData Sport_Lib_ServiceAbstract Friday, June 7, 13
  • 7. DI for a 5 year old When you go and get things out of the refrigerator for yourself, you can cause problems. You might leave the door open, you might get something Mommy or Daddy doesn't want you to have. You might even be looking for something we don't even have or which has expired. What you should be doing is stating a need, "I need something to drink with lunch," and then we will make sure you have something when you sit down to eat. Friday, June 7, 13
  • 8. Something like this... Application needs Foo, which needs Bar, which needs Bim, so: Application creates Bim Application creates Bar and gives it Bim Application creates Foo and gives it Bar Application calls Foo Foo calls Bar Bar does something Friday, June 7, 13
  • 9. The Service Container Dependency Injection Round 1 Friday, June 7, 13
  • 10. class Mailer { private $transport; public function __construct($transport) { $this->transport = $transport; } // ... } Symfony2 Example Friday, June 7, 13
  • 11. class Mailer { private $transport; public function __construct($transport) { $this->transport = $transport; } // ... } use SymfonyComponentDependencyInjectionContainerBuilder; $container = new ContainerBuilder(); $container->register('mailer', 'Mailer'); Symfony2 Example Friday, June 7, 13
  • 12. class Mailer { private $transport; public function __construct($transport) { $this->transport = $transport; } // ... } use SymfonyComponentDependencyInjectionContainerBuilder; $container = new ContainerBuilder(); $container->register('mailer', 'Mailer'); use SymfonyComponentDependencyInjectionContainerBuilder; $container = new ContainerBuilder(); $container ->register('mailer', 'Mailer') ->addArgument('sendmail'); Symfony2 Example Friday, June 7, 13
  • 13. class NewsletterManager { private $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } // ... } Friday, June 7, 13
  • 14. class NewsletterManager { private $mailer; public function __construct(Mailer $mailer) { $this->mailer = $mailer; } // ... } use SymfonyComponentDependencyInjectionContainerBuilder; use SymfonyComponentDependencyInjectionReference; $container = new ContainerBuilder(); $container->setParameter('mailer.transport', 'sendmail'); $container ->register('mailer', 'Mailer') ->addArgument('%mailer.transport%'); $container ->register('newsletter_manager', 'NewsletterManager') ->addArgument(new Reference('mailer')); Friday, June 7, 13
  • 15. use SymfonyComponentDependencyInjectionContainerBuilder; $container = new ContainerBuilder(); $newsletterManager = $container->get('newsletter_manager'); Friday, June 7, 13
  • 16. Inversion Of Control Pattern The control of the dependencies is inversed from one being called to the one calling. Friday, June 7, 13
  • 17. Container Newsletter Manager Mailer transport = sendmail Friday, June 7, 13
  • 18. Container Newsletter Manager Mailer # src/Acme/HelloBundle/Resources/config/ services.yml parameters: # ... mailer.transport: sendmail services: mailer: class: Mailer arguments: [%mailer.transport%] newsletter_manager: class: NewsletterManager calls: - [ setMailer, [ @mailer ] ] transport = sendmail Friday, June 7, 13
  • 20. Tips Test first in isolation Don’t need to wire together to test (Eg Environment etc) integration tests are expensive. When you do wire together with test/mock classes as needed Duck Type your code / Use interfaces Friday, June 7, 13
  • 22. $container = new Pimple(); // define some parameters $container['cookie_name'] = 'SESSION_ID'; $container['session_storage_class'] = 'SessionStorage'; Friday, June 7, 13
  • 23. $container = new Pimple(); // define some parameters $container['cookie_name'] = 'SESSION_ID'; $container['session_storage_class'] = 'SessionStorage'; // define some objects $container['session_storage'] = function ($c) { return new $c['session_storage_class']($c['cookie_name']); }; $container['session'] = function ($c) { return new Session($c['session_storage']); }; Friday, June 7, 13
  • 24. Clever DI with Bindings Friday, June 7, 13
  • 25. Laravel 4 example class MyConcreteClass implements MyInterface { Friday, June 7, 13
  • 26. Laravel 4 example class MyConcreteClass implements MyInterface { class MyClass { public function __construct(MyInterface $my_injection) { $this->my_injection = $my_injection; } } App::bind('MyInterface', 'MyConcreteClass'); Friday, June 7, 13
  • 27. Cleverer DI with Injection Points & Bindings Friday, June 7, 13
  • 28. Google Guice Guice alleviates the need for factories and the use of ‘new’ in your ‘Java’a code Think of Guice's @Inject as the new new. You will still need to write factories in some cases, but your code will not depend directly on them. Your code will be easier to change, unit test and reuse in other contexts. Ray.DI Friday, June 7, 13
  • 29. interface MailerInterface {} PHP Google Guice Clone Ray.DI Friday, June 7, 13
  • 30. class Mailer implements MailerInterface { private $transport; /** * @Inject * @Named("transport_type") */ public function __construct($transport) { $this->transport = $transport; } } interface MailerInterface {} PHP Google Guice Clone Ray.DI Friday, June 7, 13
  • 31. class Mailer implements MailerInterface { private $transport; /** * @Inject * @Named("transport_type") */ public function __construct($transport) { $this->transport = $transport; } } interface MailerInterface {} class NewsletterManager { public $mailer; /** * @Inject */ public function __construct(MailerInterface $mailer) { $this->mailer = $mailer; } } PHP Google Guice Clone Ray.DI Friday, June 7, 13
  • 32. class NewsletterModule extends AbstractModule { protected function configure() { $this->bind()->annotatedWith('transport_type')->toInstance('sendmail'); $this->bind('MailerInterface')->to('Mailer'); } } Friday, June 7, 13
  • 33. class NewsletterModule extends AbstractModule { protected function configure() { $this->bind()->annotatedWith('transport_type')->toInstance('sendmail'); $this->bind('MailerInterface')->to('Mailer'); } } $di = Injector::create([new NewsletterModule]); $newsletterManager = $di->getInstance('NewsletterManager'); Friday, June 7, 13
  • 34. class NewsletterModule extends AbstractModule { protected function configure() { $this->bind()->annotatedWith('transport_type')->toInstance('sendmail'); $this->bind('MailerInterface')->to('Mailer'); } } $di = Injector::create([new NewsletterModule]); $newsletterManager = $di->getInstance('NewsletterManager'); $works = ($newsletterManager->mailer instanceof MailerInterface); Friday, June 7, 13
  • 35. Problems?/Gochas 1. Overly abstracted code 2. Easy to go crazy with it 3. Too many factory classes 4. Easy to loose what data is where 5. Container is like super global variable Friday, June 7, 13
  • 38. The Problem function addPost() { $log->writeToLog("Entering addPost"); // Business Logic $log->writeToLog("Leaving addPost"); } Friday, June 7, 13
  • 39. The Problem function addPost() { $log->writeToLog("Entering addPost"); // Business Logic $log->writeToLog("Leaving addPost"); } function addPost() { $authentication->validateAuthentication($user); $authorization->validateAccess($user); // Business Logic } Friday, June 7, 13
  • 40. Core Class Aspect Class AOP Framework Proxy Class Continue Process Friday, June 7, 13
  • 41. Lithium Example -Logging in your model namespace appmodels; use lithiumutilcollectionFilters; use lithiumutilLogger; Filters::apply('appmodelsPost', 'save', function($self, $params, $chain) { Logger::write('info', $params['data']['title']); return $chain->next($self, $params, $chain); }); Friday, June 7, 13
  • 42. Dispatcher::applyFilter('run', function($self, $params, $chain) { $key = md5($params['request']->url); if($cache = Cache::read('default', $key)) { return $cache; } $result = $chain->next($self, $params, $chain); Cache::write('default', $key, $result, '+1 day'); return $result; }); Lithium Example -Caching Friday, June 7, 13
  • 51. /** * NotOnWeekends * * @Annotation * @Target("METHOD") */ final class NotOnWeekends { } Create Annotation Create Real Class - Billing service Friday, June 7, 13
  • 52. /** * NotOnWeekends * * @Annotation * @Target("METHOD") */ final class NotOnWeekends { } Create Annotation class RealBillingService { /** * @NotOnWeekends */ chargeOrder(PizzaOrder $order, CreditCard $creditCard) { Create Real Class - Billing service Friday, June 7, 13
  • 53. class WeekendBlocker implements MethodInterceptor { public function invoke(MethodInvocation $invocation) { $today = getdate(); if ($today['weekday'][0] === 'S') { throw new RuntimeException( $invocation->getMethod()->getName() . " not allowed on weekends!" ); } return $invocation->proceed(); } } Interception Logic Friday, June 7, 13
  • 54. $bind = new Bind; $matcher = new Matcher(new Reader); $interceptors = [new WeekendBlocker]; $pointcut = new Pointcut( $matcher->any(), $matcher->annotatedWith('RayAopSampleAnnotationNotOnWeekends'), $interceptors ); $bind->bind('RayAopSampleAnnotationRealBillingService', [$pointcut]); $billing = new Weaver(new RealBillingService, $bind); try { echo $billing->chargeOrder(); } catch (RuntimeException $e) { echo $e->getMessage() . "n"; exit(1); } Binding on Annotation Friday, June 7, 13
  • 55. $bind = new Bind; $bind->bindInterceptors('chargeOrder', [new WeekendBlocker]); $billingService = new Weaver(new RealBillingService, $bind); try { echo $billingService->chargeOrder(); } catch (RuntimeException $e) { echo $e->getMessage() . "n"; exit(1); } Explicit Method Binding Friday, June 7, 13