-
Notifications
You must be signed in to change notification settings - Fork 2
Feature: Recursive Dependency Injection
A basic part of any dependency injection framework is the ability to inject the dependencies of your dependencies. Doing so permits proper separation of concern in configuration, and handles the potentially complicated task of wiring up the right instance with other instances that need it.
Squirt calls each instance of a class configured via Squirt a "service". Hence the name of the primary user class is the SquirtServiceBuilder. The idea is that normally a behaves as a singleton, identified by it's name, but with none of the testability problems of actual singletons. So if one requests an instance of a Logger via $squirtServiceBuilder->get('LOGGER') multiple times, the same object will be returned each time. This prevents wasteful instantiation for things like database connections, and simplifies the sharing of single objects between user objects that depend on it.
One of the differences in Squirt with some other dependency injection frameworks is that services are identified by a user-defined name, and not by the actual class. This provides simple and straightforward flexibility for things like using multiple database connections at once, without having to duplicate the database connection class. In squirt, if there are two different services, then each just needs a different name in order to have a different configuration.
In order to define a recursive dependency injection, one uses a squirt config file like:
return array(
'services' => array(
'LOGGER' => array(
'class' => 'MyApp\Logger',
'params' => array(
'logFile' => '/var/log/app.log'
)
),
'GUZZLE_CLIENT' => array(
'class' => 'MyApp\GuzzleClient',
'params' => array(
'logger' => '{LOGGER}'
)
),
'APP' => array(
'class' => 'MyApp\App',
'params' => array(
'logger' => '{LOGGER}',
'client' => '{GUZZLE_CLIENT}',
'url' => 'https://github.com'
)
)
)
);In this example, when one requests an instance of the "APP" service, Squirt takes care of instantiating both a "LOGGER" and a "GUZZLE_CLIENT" and injecting those into your "APP". Note that the same "LOGGER" is injected into both the "APP" and the "GUZZLE_CLIENT" so they both will log messages in the same manner.
Injected object dependencies are injected right along with PHP primitive values like strings and numbers in a straightforward manner. One just needs to wrap the name of the service inside {}.