This document provides an overview of dependency injection (DI) and how it is implemented in Drupal 8. It begins by explaining DI as a design pattern that allows code to be more reusable, testable and ignorant of dependencies. It then discusses how frameworks like Symfony implement DI using a service container that is configured to inject dependencies. In Drupal 8, services are defined in YAML files and the container is configured using compiler passes. Core services can be accessed directly or by wiring classes into the container as event subscribers or using a factory method for controllers.
In this talk, I’m introducing Pegomock, a mocking framework for Go, that I have written over the last 2 years. By quickly going through the idea of Dependency Injection, I'm explaining why mocks are useful in general. Afterwards, I'm diving a bit deeper into how to use Pegomock and why I think it is better than its alternatives.
Managing an OSGi Framework with Apache Felix Web ConsoleFelix Meschberger
Initially created to aid in the simple maintenance of the OSGi framework and the application during the early development of Apache Sling, the Web Console soon attracted interest from the OSGi community. Three years later, the Apache Felix Web Console 3.0 has just been released and provides an extensible console for Web based management of an OSGi framework. This talk will introduce the functionality of the core Web Console as well as some of its existing plugins and the extension points of the Web Console where developers might want to hook up to. To round it up a simple Web Console plugin will be developed and deployed.
Being Functional on Reactive Streams with Spring ReactorMax Huang
The journey begins with using Java 8 introduced Optional/Stream/CompletableFuture more functional, after which Reactive Streams is introduced with a homemade implementation that is ultimately made functional to increase usability. Finally Spring Reactor (Project Reactor) is presented and used for building a device simulator periodically reporting data to device controller.
In this talk, I’m introducing Pegomock, a mocking framework for Go, that I have written over the last 2 years. By quickly going through the idea of Dependency Injection, I'm explaining why mocks are useful in general. Afterwards, I'm diving a bit deeper into how to use Pegomock and why I think it is better than its alternatives.
Managing an OSGi Framework with Apache Felix Web ConsoleFelix Meschberger
Initially created to aid in the simple maintenance of the OSGi framework and the application during the early development of Apache Sling, the Web Console soon attracted interest from the OSGi community. Three years later, the Apache Felix Web Console 3.0 has just been released and provides an extensible console for Web based management of an OSGi framework. This talk will introduce the functionality of the core Web Console as well as some of its existing plugins and the extension points of the Web Console where developers might want to hook up to. To round it up a simple Web Console plugin will be developed and deployed.
Being Functional on Reactive Streams with Spring ReactorMax Huang
The journey begins with using Java 8 introduced Optional/Stream/CompletableFuture more functional, after which Reactive Streams is introduced with a homemade implementation that is ultimately made functional to increase usability. Finally Spring Reactor (Project Reactor) is presented and used for building a device simulator periodically reporting data to device controller.
Dependency injection is a powerful technique allowing different parts of a system to collaborate with each other. Injection is the passing of a dependency (such as a service or database connection) to an object that would use it. This way, the object need not change because the outside service changed. This often also allows the object to be more easily tested by injecting a mock or stub service as the dependency.
I present four design patterns that make your development easier and better. Design patterns are a fantastic way to make more readable code, as they make use of common ideas that many developers know and use. These patterns are tried and tested in the enterprise world.
The first one is dependency injection. This covers putting the variables that a class needs to function preferably inside a constructor.
The second one is the factory pattern. A factory moves the responsibility of instantiating an object to a third-party class.
The third one is dependency injection. This allows us to place a class' dependencies at one time, making it easy to come back and see what the class needs to survive.
Finally, we discuss the chain of responsibility. This allows complex operations to be handled by a chain of classes. Each class in the chain determines whether it is capable of handling the request and, if so, it returns the result.
This talk represents the combined experience from several web development teams who have been using Symfony2 since months already to create high profile production applications. The aim is to give the audience real world advice on how to best leverage Symfony2, the current rough spots and how to work around them. Aside from covering how to implement functionality in Symfony2, this talk will also cover topics such as how to best integrate 3rd party bundles and where to find them as well as how to deploy the code and integrate into the entire server setup.
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
Slides from my talk presented during Dutch PHP Conference in Amsterdam - 25 June 2016
More Domain-Driven Design related content at: https://domaincentric.net/
A Series of Fortunate Events - Symfony Camp Sweden 2014Matthias Noback
What is an event really? How can you best describe an event in your code? What types of events are there, and how do you decide whether or not to implement something as an event?
In this talk we start with a straightforward command-only piece of code. We extract events from it and start moving the event handling code out, trying different design patterns on the way. First we try Observer. Then we introduce event data, event handlers and a Mediator between our code and the event handlers. Finally we pick a well-known event dispatcher implementation (the Symfony EventDispatcher) and see how it uses the Chain of Responsibility design pattern to control the entire flow of a web application request.
In the end I will answer some burning questions like: is it safe to use events all over the place and rely on event handlers to do some really important stuff? How do I overcome the indirection in my event-driven code? And how can I quickly find out what happens where?
One of the most prolific parts of Zend Framework 2 is the Service Manager. Its many nooks and crannies dictate much of what happens inside our Zend Framework 2 applications and is incredibly powerful. Let's look into exactly what the Service Manager allows us to do and how we can take advantage of it for cleaner, and faster, code.
A Series of Fortunate Events - PHP Benelux Conference 2015Matthias Noback
What is an event really? How can you best describe an event in your code? What types of events are there, and how do you decide whether or not to implement something as an event?
In this talk we start with a straightforward command-only piece of code. We extract events from it and start moving the event handling code out, trying different design patterns on the way. First we try Observer. Then we introduce event data, event handlers and a Mediator between our code and the event handlers. Finally we pick a well-known event dispatcher implementation (the Symfony EventDispatcher) and see how it uses the Chain of Responsibility design pattern to control the entire flow of a web application request.
In the end I will answer some burning questions like: is it safe to use events all over the place and rely on event handlers to do some really important stuff? How do I overcome the indirection in my event-driven code? And how can I quickly find out what happens where?
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
While Singletons have become a Pattern-Non-Grata over the years, you still find it surprisingly often in PHP applications and frameworks. This talk will explain what the Singleton pattern is, how it works in PHP and why you should avoid it in your application.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
Threats to mobile devices are more prevalent and increasing in scope and complexity. Users of mobile devices desire to take full advantage of the features
available on those devices, but many of the features provide convenience and capability but sacrifice security. This best practices guide outlines steps the users can take to better protect personal devices and information.
Dependency injection is a powerful technique allowing different parts of a system to collaborate with each other. Injection is the passing of a dependency (such as a service or database connection) to an object that would use it. This way, the object need not change because the outside service changed. This often also allows the object to be more easily tested by injecting a mock or stub service as the dependency.
I present four design patterns that make your development easier and better. Design patterns are a fantastic way to make more readable code, as they make use of common ideas that many developers know and use. These patterns are tried and tested in the enterprise world.
The first one is dependency injection. This covers putting the variables that a class needs to function preferably inside a constructor.
The second one is the factory pattern. A factory moves the responsibility of instantiating an object to a third-party class.
The third one is dependency injection. This allows us to place a class' dependencies at one time, making it easy to come back and see what the class needs to survive.
Finally, we discuss the chain of responsibility. This allows complex operations to be handled by a chain of classes. Each class in the chain determines whether it is capable of handling the request and, if so, it returns the result.
This talk represents the combined experience from several web development teams who have been using Symfony2 since months already to create high profile production applications. The aim is to give the audience real world advice on how to best leverage Symfony2, the current rough spots and how to work around them. Aside from covering how to implement functionality in Symfony2, this talk will also cover topics such as how to best integrate 3rd party bundles and where to find them as well as how to deploy the code and integrate into the entire server setup.
The IoC Hydra - Dutch PHP Conference 2016Kacper Gunia
Slides from my talk presented during Dutch PHP Conference in Amsterdam - 25 June 2016
More Domain-Driven Design related content at: https://domaincentric.net/
A Series of Fortunate Events - Symfony Camp Sweden 2014Matthias Noback
What is an event really? How can you best describe an event in your code? What types of events are there, and how do you decide whether or not to implement something as an event?
In this talk we start with a straightforward command-only piece of code. We extract events from it and start moving the event handling code out, trying different design patterns on the way. First we try Observer. Then we introduce event data, event handlers and a Mediator between our code and the event handlers. Finally we pick a well-known event dispatcher implementation (the Symfony EventDispatcher) and see how it uses the Chain of Responsibility design pattern to control the entire flow of a web application request.
In the end I will answer some burning questions like: is it safe to use events all over the place and rely on event handlers to do some really important stuff? How do I overcome the indirection in my event-driven code? And how can I quickly find out what happens where?
One of the most prolific parts of Zend Framework 2 is the Service Manager. Its many nooks and crannies dictate much of what happens inside our Zend Framework 2 applications and is incredibly powerful. Let's look into exactly what the Service Manager allows us to do and how we can take advantage of it for cleaner, and faster, code.
A Series of Fortunate Events - PHP Benelux Conference 2015Matthias Noback
What is an event really? How can you best describe an event in your code? What types of events are there, and how do you decide whether or not to implement something as an event?
In this talk we start with a straightforward command-only piece of code. We extract events from it and start moving the event handling code out, trying different design patterns on the way. First we try Observer. Then we introduce event data, event handlers and a Mediator between our code and the event handlers. Finally we pick a well-known event dispatcher implementation (the Symfony EventDispatcher) and see how it uses the Chain of Responsibility design pattern to control the entire flow of a web application request.
In the end I will answer some burning questions like: is it safe to use events all over the place and rely on event handlers to do some really important stuff? How do I overcome the indirection in my event-driven code? And how can I quickly find out what happens where?
Singletons in PHP - Why they are bad and how you can eliminate them from your...go_oh
While Singletons have become a Pattern-Non-Grata over the years, you still find it surprisingly often in PHP applications and frameworks. This talk will explain what the Singleton pattern is, how it works in PHP and why you should avoid it in your application.
DevOps and Testing slides at DASA ConnectKari Kakkonen
My and Rik Marselis slides at 30.5.2024 DASA Connect conference. We discuss about what is testing, then what is agile testing and finally what is Testing in DevOps. Finally we had lovely workshop with the participants trying to find out different ways to think about quality and testing in different parts of the DevOps infinity loop.
Threats to mobile devices are more prevalent and increasing in scope and complexity. Users of mobile devices desire to take full advantage of the features
available on those devices, but many of the features provide convenience and capability but sacrifice security. This best practices guide outlines steps the users can take to better protect personal devices and information.
Securing your Kubernetes cluster_ a step-by-step guide to success !KatiaHIMEUR1
Today, after several years of existence, an extremely active community and an ultra-dynamic ecosystem, Kubernetes has established itself as the de facto standard in container orchestration. Thanks to a wide range of managed services, it has never been so easy to set up a ready-to-use Kubernetes cluster.
However, this ease of use means that the subject of security in Kubernetes is often left for later, or even neglected. This exposes companies to significant risks.
In this talk, I'll show you step-by-step how to secure your Kubernetes cluster for greater peace of mind and reliability.
Sudheer Mechineni, Head of Application Frameworks, Standard Chartered Bank
Discover how Standard Chartered Bank harnessed the power of Neo4j to transform complex data access challenges into a dynamic, scalable graph database solution. This keynote will cover their journey from initial adoption to deploying a fully automated, enterprise-grade causal cluster, highlighting key strategies for modelling organisational changes and ensuring robust disaster recovery. Learn how these innovations have not only enhanced Standard Chartered Bank’s data infrastructure but also positioned them as pioneers in the banking sector’s adoption of graph technology.
GraphRAG is All You need? LLM & Knowledge GraphGuy Korland
Guy Korland, CEO and Co-founder of FalkorDB, will review two articles on the integration of language models with knowledge graphs.
1. Unifying Large Language Models and Knowledge Graphs: A Roadmap.
https://arxiv.org/abs/2306.08302
2. Microsoft Research's GraphRAG paper and a review paper on various uses of knowledge graphs:
https://www.microsoft.com/en-us/research/blog/graphrag-unlocking-llm-discovery-on-narrative-private-data/
Essentials of Automations: The Art of Triggers and Actions in FMESafe Software
In this second installment of our Essentials of Automations webinar series, we’ll explore the landscape of triggers and actions, guiding you through the nuances of authoring and adapting workspaces for seamless automations. Gain an understanding of the full spectrum of triggers and actions available in FME, empowering you to enhance your workspaces for efficient automation.
We’ll kick things off by showcasing the most commonly used event-based triggers, introducing you to various automation workflows like manual triggers, schedules, directory watchers, and more. Plus, see how these elements play out in real scenarios.
Whether you’re tweaking your current setup or building from the ground up, this session will arm you with the tools and insights needed to transform your FME usage into a powerhouse of productivity. Join us to discover effective strategies that simplify complex processes, enhancing your productivity and transforming your data management practices with FME. Let’s turn complexity into clarity and make your workspaces work wonders!
Dr. Sean Tan, Head of Data Science, Changi Airport Group
Discover how Changi Airport Group (CAG) leverages graph technologies and generative AI to revolutionize their search capabilities. This session delves into the unique search needs of CAG’s diverse passengers and customers, showcasing how graph data structures enhance the accuracy and relevance of AI-generated search results, mitigating the risk of “hallucinations” and improving the overall customer journey.
GraphSummit Singapore | The Future of Agility: Supercharging Digital Transfor...Neo4j
Leonard Jayamohan, Partner & Generative AI Lead, Deloitte
This keynote will reveal how Deloitte leverages Neo4j’s graph power for groundbreaking digital twin solutions, achieving a staggering 100x performance boost. Discover the essential role knowledge graphs play in successful generative AI implementations. Plus, get an exclusive look at an innovative Neo4j + Generative AI solution Deloitte is developing in-house.
Communications Mining Series - Zero to Hero - Session 1DianaGray10
This session provides introduction to UiPath Communication Mining, importance and platform overview. You will acquire a good understand of the phases in Communication Mining as we go over the platform with you. Topics covered:
• Communication Mining Overview
• Why is it important?
• How can it help today’s business and the benefits
• Phases in Communication Mining
• Demo on Platform overview
• Q/A
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024Neo4j
Neha Bajwa, Vice President of Product Marketing, Neo4j
Join us as we explore breakthrough innovations enabled by interconnected data and AI. Discover firsthand how organizations use relationships in data to uncover contextual insights and solve our most pressing challenges – from optimizing supply chains, detecting fraud, and improving customer experiences to accelerating drug discoveries.
Epistemic Interaction - tuning interfaces to provide information for AI supportAlan Dix
Paper presented at SYNERGY workshop at AVI 2024, Genoa, Italy. 3rd June 2024
https://alandix.com/academic/papers/synergy2024-epistemic/
As machine learning integrates deeper into human-computer interactions, the concept of epistemic interaction emerges, aiming to refine these interactions to enhance system adaptability. This approach encourages minor, intentional adjustments in user behaviour to enrich the data available for system learning. This paper introduces epistemic interaction within the context of human-system communication, illustrating how deliberate interaction design can improve system understanding and adaptation. Through concrete examples, we demonstrate the potential of epistemic interaction to significantly advance human-computer interaction by leveraging intuitive human communication strategies to inform system design and functionality, offering a novel pathway for enriching user-system engagements.
Unlocking Productivity: Leveraging the Potential of Copilot in Microsoft 365, a presentation by Christoforos Vlachos, Senior Solutions Manager – Modern Workplace, Uni Systems
Pushing the limits of ePRTC: 100ns holdover for 100 daysAdtran
At WSTS 2024, Alon Stern explored the topic of parametric holdover and explained how recent research findings can be implemented in real-world PNT networks to achieve 100 nanoseconds of accuracy for up to 100 days.
UiPath Test Automation using UiPath Test Suite series, part 5DianaGray10
Welcome to UiPath Test Automation using UiPath Test Suite series part 5. In this session, we will cover CI/CD with devops.
Topics covered:
CI/CD with in UiPath
End-to-end overview of CI/CD pipeline with Azure devops
Speaker:
Lyndsey Byblow, Test Suite Sales Engineer @ UiPath, Inc.
2. Intro
● Rudimentary understanding of OOP assumed
● Big changes in D8
● Not enough time to explain ALL THE THINGS
but I'll provide a list of resources for a deeper
dive into DI
3. Agenda
● DI as a design pattern
● DI from a framework perspective
● Symfony-style DI
● DI in Drupal 8
4. Agenda
● DI as a design pattern
● DI from a framework perspective
● Symfony-style DI
● DI in Drupal 8
Why?
How?
10. Doing It Wrong
1. An example in procedural code
2. An example in Object Oriented code
11. class Notifier {
private $mailer;
public function __construct() {
$this->mailer = new Mailer();
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
12. class Notifier {
private $mailer;
public function __construct() {
$this->mailer = new Mailer('sendmail');
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
13. class Notifier {
private $mailer;
public function __construct(Mailer $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
14. class Notifier {
private $mailer;
public function __construct(Mailer $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
$mailer = new Mailer();
$notifier = new Notifier($mailer);
15. Goal: we want to write code
that is...
✔Clutter-free
✔Reusable
✔Testable
16. Goal: we want to write code
that is...
✔Clutter-free
✔Reusable
✔Testable
Ignorant
18. class Notifier {
private $mailer;
public function __construct(Mailer $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
$mailer = new Mailer();
$notifier = new Notifier($mailer);
19. class Notifier {
private $mailer;
public function
__construct(MailerInterface $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
$mailer = new SpecialMailer();
$notifier = new Notifier($mailer);
20. class Notifier {
private $mailer;
public function
__construct(MailerInterface $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
$mailer = new SpecialMailer();
$notifier = new Notifier($mailer);
Constructor Injection
24. class Notifier {
private $mailer;
public function
setMailer(MailerInterface $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($msg);
}
}
$mailer = new Mailer();
$notifier = new Notifier();
$notifier->setMailer($mailer);
25. class Notifier {
private $mailer;
public function
setMailer(MailerInterface $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($msg);
}
}
$mailer = new Mailer();
$notifier = new Notifier();
$notifier->setMailer($mailer);
Setter Injection
26. Interface Injection
Like setter injection, except there is an
interface for each dependency's setter
method.
Very verbose
Not very common
31. class Notifier {
private $mailer;
public function
__construct(MailerInterface $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
$mailer = new Mailer();
$notifier = new Notifier($mailer);
32. class Notifier {
private $mailer;
public function
__construct(MailerInterface $m) {
$this->mailer = $m;
}
public function notify() {
...
$this->mailer->send($from, $to, $msg);
...
}
}
$mailer = new Mailer();
$notifier = new Notifier($mailer);?
34. Where does injection happen?
➔ Manual injection
➔ Use a factory
➔ Use a container / injector
35. Using DI in a Framework
Dependency Injector
==
Dependency Injection Container (DIC)
==
IoC Container
==
Service Container
36. The Service Container
➔ Assumes responsibility for constructing
object graphs (i.e. instantiating your
classes with their dependencies)
➔ Uses configuration data to know how to
do this
➔ Allows infrastructure logic to be kept
separate from application logic
37. Objects as Services
A service is an object that provides some kind of
globally useful functionality
43. How does it work?
➔ Service keys map to service definitions
➔ Definitions specify which class to
instantiate and what its dependencies
are
➔ Dependencies are specified as
references to other services (using
service keys)
➔ Keys are unique per object graph
➔ $container->getService('some_service')
44. Service Keys
Each key corresponds to a unique object graph, e.g.
'english_mailer' corresponds to
new Mailer(new EnglishSpellchecker())
'french_mailer' corresponds to
new Mailer(new FrenchSpellchecker())
46. Scope
The scope of a service is the context under which
the service key refers to the same instance.
47. Common Scopes
Container scope (aka Singleton scope)
The container returns the same instance every time
a client requests that service
Prototype scope (aka no scope)
The container returns a new instance every time a
client requests that service
Request scope
Every request for the service within the context of
an HTTP request will get the same instance.
48. Service Locator vs. DI
class SomeClass {
public function __construct(Locator $sl) {
$this->myDep = $sl->get('some_service');
}
}
In DI, calls like
$container->get('some_service')
should only happen at the entry point to the
application
53. Symfony's DI Component
➔ Service keys are strings, e.g. 'some_service'
➔ Service definitions, in addition to specifying
which class to instantiate and what
constructor arguments to pass in, allow you to
specify additional methods to call on the
object after instantiation
54. Symfony's DI Component
➔ Default scope: container
➔ Can be configured in PHP, XML or YAML
➔ Can be “compiled” down to plain PHP
56. “Compiling” the container
It's too expensive to parse configuration on
every request.
Parse once and put the result into a PHP class
that hardcodes a method for each service.
57. “Compiling” the container
Class service_container extends Container {
/**
* Gets the 'example' service.
*/
protected function getExampleService()
{
return $this->services['example'] = new
SomeNamespaceSomeClass();
}
}
58. “Synthetic” Services
A synthetic service is one that is not instantiated
by the container – the container just gets told
about it so it can then treat it as a service when
anything has a dependency on it.
59. Bundles
Bundles are Symfony's answer to plugins or
modules, i.e. prepackaged sets of functionality
implementing a particular feature, e.g. a blog.
Bundles need to be able to interact with the
container so they provide a class implementing
the BundleInterace which allows them to do so.
60. Compiler passes
Compiler passes give you an opportunity to
manipulate other service definitions that have
been registered with the service container.
Use them to:
● Specify a different class for a given service id
● Process “tagged” services
61. Tagged Services
You can add tags to your services when you
define them. This flags them for some kind of
special processing (in a compiler pass).
For example, this mechanism is used to register
event subscribers (services tagged with
'event_subscriber') to Symfony's event
dispatcher
63. Symfony's Event Dispatcher
➔ Dispatcher dispatches events such as
Kernel::Request
➔ Can be used to dispatch any kind of custom
event
➔ Event listeners are registered to the
dispatcher and notified when an event fires
➔ Event subscribers are classes that provide
multiple event listeners for different events
64. Symfony's Event Dispatcher
➔ A compiler pass registers all subscribers to
the dispatcher, using their service IDs
➔ The dispatcher holds a reference to the
service container
➔ Can therefore instantiate “subscriber
services” with their dependencies
65. class RegisterKernelListenersPass implements
CompilerPassInterface {
public function process(ContainerBuilder $container) {
$definition = $container
->getDefinition('event_dispatcher');
$services = $container
->findTaggedServiceIds('event_subscriber');
foreach ($services as $id => $attributes) {
$definition->addMethodCall('addSubscriberService',
array($id, $class));
}
}
}
A compiler pass iterates over the
tagged services
66. class CoreBundle extends Bundle {
public function build(ContainerBuilder $container)
{
...
// Compiler pass for event subscribers.
$container->addCompilerPass(new
RegisterKernelListenersPass());
...
}
}
Register the compiler pass
70. class AliasManager implements AliasManagerInterface {
...
public function __construct(Connection $connection,
AliasWhitelist $whitelist, LanguageManager
$language_manager) {
$this->connection = $connection;
$this->languageManager = $language_manager;
$this->whitelist = $whitelist;
}
...
}
AliasManager's Constructor
71. 2 ways you can use core's
services
1. From procedural code, using a helper
(essentially a service locator)
2. Write OO code and get wired into the
container
76. Controllers as Services?
➔ Controllers have dependencies on services
➔ Whether they should be directly wired into
the container is a hotly debated topic in the
Symfony community
➔ Recommended way in D8 is not to make
controllers themselves services but to
implement a special interface that has a
factory method which accepts the container
➔ See book module for an example!
78. Where does it all happen?
➔ The Drupal Kernel:
core/lib/Drupal/Core/DrupalKernel.php
➔ Services are defined in:
core/core.services.yml
➔ Compiler passes get added in:
core/lib/Drupal/Core/CoreBundle.php
➔ Compiler pass classes live here:
core/lib/Drupal/Core/DependencyInjection/
Compiler/...
79. What about modules?
➔ Services are defined in:
mymodule/mymodule.services.yml
➔ Compiler passes get added in:
mymodule/lib/Drupal/mymodule/MymoduleB
undle.php
➔ All classes, including compiler pass classes,
must live in
mymodule/lib/Drupal/mymodule/