From 8562a52a4c7496b1f6dfb6ff7b028a08963ef79c Mon Sep 17 00:00:00 2001 From: froschdesign Date: Sun, 14 Feb 2016 18:27:10 +0100 Subject: [PATCH 1/6] [Docs] - Fixes #12 - Check For Blockquotes In Docs --- doc/book/zend.di.definitions.md | 2 +- doc/book/zend.di.instance-manager.md | 2 +- doc/book/zend.di.introduction.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/book/zend.di.definitions.md b/doc/book/zend.di.definitions.md index d56f67c7..9043edd4 100644 --- a/doc/book/zend.di.definitions.md +++ b/doc/book/zend.di.definitions.md @@ -11,7 +11,7 @@ Definitions are introduced to the Zend\\Di\\Di object through a definition list Zend\\Di\\DefinitionList (SplDoublyLinkedList). Order is important. Definitions in the front of the list will be consulted on a class before definitions at the end of the list. -> ## Note +> ### Note Regardless of what kind of Definition strategy you decide to use, it is important that your autoloaders are already setup and ready to use. diff --git a/doc/book/zend.di.instance-manager.md b/doc/book/zend.di.instance-manager.md index 8fe166b9..cf59fcca 100644 --- a/doc/book/zend.di.instance-manager.md +++ b/doc/book/zend.di.instance-manager.md @@ -150,7 +150,7 @@ instance configuration to that alias; as opposed to attaching that configuration To demonstrate both of these points, we'll look at a use case where we'll have two separate DbAdapters, one will be for read-only operations, the other will be for read-write operations: -> ## Note +> ### Note Aliases can also have parameters registered at alias time ```php diff --git a/doc/book/zend.di.introduction.md b/doc/book/zend.di.introduction.md index dbeba152..38455175 100644 --- a/doc/book/zend.di.introduction.md +++ b/doc/book/zend.di.introduction.md @@ -18,7 +18,7 @@ Schindler's Learning DI](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php), or [Fabien Potencier's Series](http://fabien.potencier.org/article/11/what-is-dependency-injection) on DI. -> ## Note +> ### Note `Zend\Di` is an example of an Inversion of Control (IoC) container. IoC containers are widely used to create object instances that have all dependencies resolved and injected. Dependency Injection containers are one form of IoC -- but not the only form. From 3d85b1eb4cfa654eaf4431ed036cc06e1ce111f3 Mon Sep 17 00:00:00 2001 From: froschdesign Date: Sun, 14 Feb 2016 18:32:53 +0100 Subject: [PATCH 2/6] [Docs] - Fixes #10 - Check Documentation For Other Things --- doc/book/zend.di.introduction.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/book/zend.di.introduction.md b/doc/book/zend.di.introduction.md index dbeba152..fd99b36a 100644 --- a/doc/book/zend.di.introduction.md +++ b/doc/book/zend.di.introduction.md @@ -23,7 +23,7 @@ Potencier's Series](http://fabien.potencier.org/article/11/what-is-dependency-in to create object instances that have all dependencies resolved and injected. Dependency Injection containers are one form of IoC -- but not the only form. Zend Framework 2 ships with another form of IoC as well, -\[ZendServiceManager\](zend.service-manager.intro). Unlike `Zend\Di`, The ServiceManager is +[Zend\\ServiceManager](http://zendframework.github.io/zend-servicemanager/). Unlike `Zend\Di`, The ServiceManager is code-driven, meaning that you typically tell it what class to instantiate, or provide a factory for the given class. This approach offers several benefits: - Easier to debug (error stacks take you into your factories, not the dependency injection From 55def9f2b14f81bc4fc2fba21a4ae91b19882bb8 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 25 Apr 2016 15:50:36 -0500 Subject: [PATCH 3/6] Edited documentation for content and formatting - Renamed files to remove `zend.di.` prefix. - Converted from bookdown to mkdocs. - Edited all documents for grammar, formatting, etc. --- doc/book/config.md | 33 +++ ....md => debugging-and-complex-use-cases.md} | 83 ++++---- doc/book/definitions.md | 139 ++++++++++++ doc/book/index.html | 10 + doc/book/index.md | 1 + doc/book/instance-manager.md | 199 ++++++++++++++++++ doc/book/intro.md | 62 ++++++ doc/book/quick-start.md | 138 ++++++++++++ doc/book/zend.di.configuration.md | 33 --- doc/book/zend.di.definitions.md | 132 ------------ doc/book/zend.di.instance-manager.md | 180 ---------------- doc/book/zend.di.introduction.md | 51 ----- doc/book/zend.di.quick-start.md | 127 ----------- doc/bookdown.json | 12 -- mkdocs.yml | 15 ++ 15 files changed, 644 insertions(+), 571 deletions(-) create mode 100644 doc/book/config.md rename doc/book/{zend.di.debugging-and-complex-use-cases.md => debugging-and-complex-use-cases.md} (53%) create mode 100644 doc/book/definitions.md create mode 100644 doc/book/index.html create mode 120000 doc/book/index.md create mode 100644 doc/book/instance-manager.md create mode 100644 doc/book/intro.md create mode 100644 doc/book/quick-start.md delete mode 100644 doc/book/zend.di.configuration.md delete mode 100644 doc/book/zend.di.definitions.md delete mode 100644 doc/book/zend.di.instance-manager.md delete mode 100644 doc/book/zend.di.introduction.md delete mode 100644 doc/book/zend.di.quick-start.md delete mode 100644 doc/bookdown.json create mode 100644 mkdocs.yml diff --git a/doc/book/config.md b/doc/book/config.md new file mode 100644 index 00000000..354e5a9f --- /dev/null +++ b/doc/book/config.md @@ -0,0 +1,33 @@ +# Configuration + +Most of the configuration for both the setup of `Definition`s as well as the +setup of the `InstanceManager` can be attained by a configuration file. This +file will produce an array (typically) and have an iterable structure. + +The top two keys are 'definition' and 'instance', each specifying values for +the definition setup and instance manager setup, respectively. + +The definition section expects the following information expressed as a PHP +array: + +```php +$config = [ + 'definition' => [ + 'compiler' => [/* @todo compiler information */], + 'runtime' => [/* @todo runtime information */], + 'class' => [ + 'instantiator' => '', // the name of the instantiator, by default this is __construct + 'supertypes' => [], // an array of supertypes the class implements + 'methods' => [ + 'setSomeParameter' => [ // a method name + 'parameterName' => [ + 'name', // string parameter name + 'type', // type or null + 'is-required', // bool + ), + ), + ), + ), + ), +); +``` diff --git a/doc/book/zend.di.debugging-and-complex-use-cases.md b/doc/book/debugging-and-complex-use-cases.md similarity index 53% rename from doc/book/zend.di.debugging-and-complex-use-cases.md rename to doc/book/debugging-and-complex-use-cases.md index 4c8a74bb..2bd52bf1 100644 --- a/doc/book/zend.di.debugging-and-complex-use-cases.md +++ b/doc/book/debugging-and-complex-use-cases.md @@ -1,9 +1,9 @@ -# Zend\\Di Debugging & Complex Use Cases +# Debugging & Complex Use Cases ## Debugging a DiC -It is possible to dump the information contained within both the Definition and InstanceManager for -a Di instance. +It is possible to dump the information contained within both the `Definition` +and `InstanceManager` for a `Zend\Di\Di` instance. The easiest way is to do the following: @@ -11,11 +11,12 @@ The easiest way is to do the following: Zend\Di\Display\Console::export($di); ``` -If you are using a RuntimeDefinition where upon you expect a particular definition to be resolve at -the first-call, you can see that information to the console display to force it to read that class: +If you are using a `RuntimeDefinition` where upon you expect a particular +definition to be resolve at the first-call, you can see that information to the +console display to force it to read that class: ```php -Zend\Di\Display\Console::export($di, array('A\ClassIWantTo\GetTheDefinitionFor')); +Zend\Di\Display\Console::export($di, ['A\ClassIWantTo\GetTheDefinitionFor']); ``` ## Complex Use Cases @@ -23,7 +24,8 @@ Zend\Di\Display\Console::export($di, array('A\ClassIWantTo\GetTheDefinitionFor') ### Interface Injection ```php -namespace Foo\Bar { +namespace Foo\Bar +{ class Baz implements BamAwareInterface { public $bam; @@ -33,9 +35,11 @@ namespace Foo\Bar { $this->bam = $bam; } } + class Bam { } + interface BamAwareInterface { public function setBam(Bam $bam); @@ -52,7 +56,8 @@ namespace { ### Setter Injection with Class Definition ```php -namespace Foo\Bar { +namespace Foo\Bar +{ class Baz { public $bam; @@ -62,21 +67,22 @@ namespace Foo\Bar { $this->bam = $bam; } } + class Bam { } } namespace { $di = new Zend\Di\Di; - $di->configure(new Zend\Di\Config(array( - 'definition' => array( - 'class' => array( - 'Foo\Bar\Baz' => array( - 'setBam' => array('required' => true) - ) - ) - ) - ))); + $di->configure(new Zend\Di\Config([ + 'definition' => [ + 'class' => [ + 'Foo\Bar\Baz' => [ + 'setBam' => ['required' => true], + ], + ], + ], + ])); $baz = $di->get('Foo\Bar\Baz'); } ``` @@ -84,7 +90,8 @@ namespace { ### Multiple Injections To A Single Injection Point ```php -namespace Application { +namespace Application +{ class Page { public $blocks; @@ -94,6 +101,7 @@ namespace Application { $this->blocks[] = $block; } } + interface Block { } @@ -107,25 +115,28 @@ namespace MyModule { namespace { include 'zf2bootstrap.php'; $di = new Zend\Di\Di; - $di->configure(new Zend\Di\Config(array( - 'definition' => array( - 'class' => array( - 'Application\Page' => array( - 'addBlock' => array( - 'block' => array('type' => 'Application\Block', 'required' => true) - ) - ) - ) - ), - 'instance' => array( - 'Application\Page' => array( - 'injections' => array( + $di->configure(new Zend\Di\Config([ + 'definition' => [ + 'class' => [ + 'Application\Page' => [ + 'addBlock' => [ + 'block' => [ + 'type' => 'Application\Block', + 'required' => true + ], + ], + ], + ], + ], + 'instance' => [ + 'Application\Page' => [ + 'injections' => [ 'MyModule\BlockOne', - 'MyModule\BlockTwo' - ) - ) - ) - ))); + 'MyModule\BlockTwo', + ], + ], + ], + ])); $page = $di->get('Application\Page'); } ``` diff --git a/doc/book/definitions.md b/doc/book/definitions.md new file mode 100644 index 00000000..a4f047e1 --- /dev/null +++ b/doc/book/definitions.md @@ -0,0 +1,139 @@ +# Dependency Definitions + +Definitions are what zend-di uses to understand the structure of the code it is +attempting to wire. This means that if you've written non-ambiguous, clear and +concise code, zend-di has a very good chance of understanding how to wire things +up without much added complexity. + +## DefinitionList + +Definitions are introduced to the `Zend\Di\Di` object through a definition list +implemented as `Zend\Di\DefinitionList` (which extends `SplDoublyLinkedList`). +Order is important. Definitions in the front of the list will be consulted on a +class before definitions at the end of the list. + +> ### Autoloading +> +> Regardless of what kind of DefinitionList strategy you decide to use, it is +> important that your autoloaders are already setup and ready to use. + +## RuntimeDefinition + +The default `DefinitionList` instantiated by `Zend\Di\Di` when no other +DefinitionList is provided is `Zend\Di\Definition\RuntimeDefinition`. The +`RuntimeDefinition` will respond to queries about classes by using PHP's +Reflection API. The `RuntimeDefinition` uses any available information inside +methods — including their signature, the names of parameters, the +type-hints of the parameters, and the default values — to determine if +something is optional or required when making a call to that method. The more +explicit you can be in your method naming and method signatures, the more likely +`Zend\Di\Definition\RuntimeDefinition` will accurately understand the structure +of your code. + +The constructor of `RuntimeDefinition` looks like the following: + +```php +public function __construct( + IntrospectionStrategy $introspectionStrategy = null, + array $explicitClasses = null +) { + $this->introspectionStrategy = ($introspectionStrategy) ?: new IntrospectionStrategy(); + if ($explicitClasses) { + $this->setExplicitClasses($explicitClasses); + } +} +``` + +The `IntrospectionStrategy` object is an object that defines the rules by which +the `RuntimeDefinition` will introspect information about your classes. Here are +the things it knows how to do: + +- Whether or not to use annotations (scanning and parsing annotations is + expensive, and thus disabled by default) +- Which method names to include in the introspection; this is a list of + patterns. By default, it registers the pattern `/^set\[A-Z\]{1}\\w\*/`. +- Which interface names represent the interface injection pattern; this is a + list of patterns. By default, the pattern `/\\w\*Aware\\w\*/` is registered. + +The constructor for the `IntrospectionStrategy` looks like this: + +```php +public function __construct(AnnotationManager $annotationManager = null) +{ + $this->annotationManager = ($annotationManager) ?: $this->createDefaultAnnotationManager(); +} +``` + +The `AnnotationManager` is not required. If you wish to create a special +`AnnotationManager` with your own annotations, and also wish to extend the +`RuntimeDefinition` to look for those annotations, this is the place to do it. + +The `RuntimeDefinition` also can be used to look up either all classes +(implicitly, which is default), or explicitly look up for particular pre-defined +classes. This is useful when your strategy for inspecting one set of classes +might differ from those of another strategy for another set of classes. This can +be achieved by using the `setExplicitClasses()` method or by passing a list of +classes as the second constructor argument of the `RuntimeDefinition`. + +## CompilerDefinition + +The `CompilerDefinition` is similar in nature to the `RuntimeDefinition` with the exception +that it can be seeded with more information for the purposes of "compiling" a +definition. Compiled definitions eliminate reflection calls and annotation +scannning, which can be a performance bottleneck in your production +applications. + +For example, let's assume we want to create a script that will create +definitions for some of our library code: + +```php +// in "package name" format +$components = [ + 'My_MovieApp', + 'My_OtherClasses', +]; + +foreach ($components as $component) { + $diCompiler = new Zend\Di\Definition\CompilerDefinition; + $diCompiler->addDirectory('/path/to/classes/' . str_replace('_', '/', $component)); + + $diCompiler->compile(); + file_put_contents( + __DIR__ . '/../data/di/' . $component . '-definition.php', + 'toArrayDefinition()->toArray(), true) . ';' + ); +} +``` + +The above creates a file for each "package", containing the full definition for +the classes defined for each. To utilize this in an application, use the +following: + +```php +protected function setupDi(Application $app) +{ + $definitionList = new DefinitionList([ + new Definition\ArrayDefinition(include __DIR__ . '/path/to/data/di/My_MovieApp-definition.php'), + new Definition\ArrayDefinition(include __DIR__ . '/path/to/data/di/My_OtherClasses-definition.php'), + $runtime = new Definition\RuntimeDefinition(), + ]); + $di = new Di($definitionList, null, new Config($this->config->di)); + $di->instanceManager()->addTypePreference('Zend\Di\LocatorInterface', $di); + $app->setLocator($di); +} +``` + +The above code would more than likely go inside your application's bootstrap or +within a `Module` class. This represents the simplest and most performant way +of configuring your DiC for usage. + +## ClassDefinition + +The idea behind using a `ClassDefinition` is two-fold. First, you may want to +override some information inside of a `RuntimeDefinition`. Secondly, you might +want to simply define your complete class's definition with an xml, ini, or php +file describing the structure. This class definition can be fed in via +`Configuration` or by directly instantiating and registering the `Definition` +with the `DefinitionList`. + +(@todo - example) diff --git a/doc/book/index.html b/doc/book/index.html new file mode 100644 index 00000000..162fdcb9 --- /dev/null +++ b/doc/book/index.html @@ -0,0 +1,10 @@ +
+
+

zend-di

+ +

Automated dependency injection and instance manager.

+ +
$ composer require zendframework/zend-di
+
+
+ diff --git a/doc/book/index.md b/doc/book/index.md new file mode 120000 index 00000000..fe840054 --- /dev/null +++ b/doc/book/index.md @@ -0,0 +1 @@ +../../README.md \ No newline at end of file diff --git a/doc/book/instance-manager.md b/doc/book/instance-manager.md new file mode 100644 index 00000000..98b6af17 --- /dev/null +++ b/doc/book/instance-manager.md @@ -0,0 +1,199 @@ +# Instance Manager + +The `InstanceManager` is responsible for any runtime information associated with +the zend-di DiC. This means that the information that goes into the instance +manager is specific to both how the particular consuming application's needs, +and even more specifically to the environment in which the application is +running. + +## Parameters + +Parameters are simply entry points for either dependencies or instance +configuration values. A class consists of a set of parameters, each uniquely +named. When writing your classes, you should attempt to not use the same +parameter name twice in the same class when you expect that that parameters is +used for either instance configuration or an object dependency. This leads to an +ambiguous parameter, and is a situation best avoided. + +Our movie finder example can be further used to explain these concepts: + +```php +namespace MyLibrary +{ + class DbAdapter + { + protected $username = null; + protected $password = null; + + public function __construct($username, $password) + { + $this->username = $username; + $this->password = $password; + } + } +} + +namespace MyMovieApp +{ + class MovieFinder + { + protected $dbAdapter = null; + + public function __construct(\MyLibrary\DbAdapter $dbAdapter) + { + $this->dbAdapter = $dbAdapter; + } + } + + class MovieLister + { + protected $movieFinder = null; + + public function __construct(MovieFinder $movieFinder) + { + $this->movieFinder = $movieFinder; + } + } +} +``` + +In the above example, the class `DbAdapter` has 2 parameters: `username` and +`password`; `MovieFinder` has one parameter: `dbAdapter`; and `MovieLister` has +one parameter: `movieFinder`. Any of these can be utilized for injection of +either dependencies or scalar values during instance configuration or during +call time. + +When looking at the above code, since the `dbAdapter` parameter and the +`movieFinder` parameter are both type-hinted with concrete types, the DiC can +assume that it can fulfill these object tendencies by itself. On the other hand, +username and password do not have type-hints and are, more than likely, scalar +in nature. Since the DiC cannot reasonably know this information, it must be +provided to the instance manager in the form of parameters. Not doing so will +force `$di->get('MyMovieApp\\MovieLister')` to throw an exception. + +The following ways of using parameters are available: + +```php +// setting instance configuration into the instance manager +$di->instanceManager()->setParameters('MyLibrary\DbAdapter', [ + 'username' => 'myusername', + 'password' => 'mypassword', +]); + +// forcing a particular dependency to be used by the instance manager +$di->instanceManager()->setParameters('MyMovieApp\MovieFinder', [ + 'dbAdapter' => new MyLibrary\DbAdapter('myusername', 'mypassword') +]); + +// passing instance parameters at call time +$movieLister = $di->get('MyMovieApp\MovieLister', [ + 'username' => $config->username, + 'password' => $config->password, +]); + +// passing a specific instance at call time +$movieLister = $di->get('MyMovieApp\MovieLister', [ + 'dbAdapter' => new MyLibrary\DbAdapter('myusername', 'mypassword') +]); +``` + +## Preferences + +In many cases, you might be using interfaces as type hints as opposed to +concrete types. Lets assume the movie example was modified in the following way: + +```php +namespace MyMovieApp +{ + interface MovieFinderInterface + { + // methods required for this type + } + + class GenericMovieFinder implements MovieFinderInterface + { + protected $dbAdapter = null; + + public function __construct(\MyLibrary\DbAdapter $dbAdapter) + { + $this->dbAdapter = $dbAdapter; + } + } + + class MovieLister + { + protected $movieFinder = null; + + public function __construct(MovieFinderInterface $movieFinder) + { + $this->movieFinder = $movieFinder; + } + } +} +``` + +What you'll notice above is that the `MovieLister` type now expects that the +dependency injected implements the `MovieFinderInterface`. This allows multiple +implementations of this base interface to be used as a dependency, if that is +what the consumer decides they want to do. As you can imagine, zend-di, by +itself would not be able to determine what kind of concrete object to use +fulfill this dependency, so this type of 'preference' needs to be made known to +the instance manager. + +To give this information to the instance manager, see the following code +example: + +```php +$di->instanceManager()->addTypePreference( + 'MyMovieApp\MovieFinderInterface', + 'MyMovieApp\GenericMovieFinder' +); + +// assuming all instance config for username, password is setup +$di->get('MyMovieApp\MovieLister'); +``` + +## Aliases + +In some situations, you'll find that you need to alias an instance. There are +two main reasons to do this. First, it creates a simpler, alternative name to +use when using the DiC, as opposed to using the full class name. Second, you +might find that you need to have the same object type in two separate contexts. +This means that when you alias a particular class, you can then attach a +specific instance configuration to that alias, as opposed to attaching that +configuration to the class name. + +To demonstrate both of these points, we'll look at a use case where we'll have +two separate database adapters. One will be for read-only operations, the other +will be for read-write operations. + +> ### Alias parameters +> +> Aliases can also have parameters registered at alias time. + +```php +// assume the MovieLister example of code from the quick start. + +$im = $di->instanceManager(); + +// add alias for short naming +$im->addAlias('movielister', 'MyMovieApp\MovieLister'); + +// add aliases for specific instances +$im->addAlias('dbadapter-readonly', 'MyLibrary\DbAdapter', [ + 'username' => $config->db->readAdapter->username, + 'password' => $config->db->readAdapter->password, +]); +$im->addAlias('dbadapter-readwrite', 'MyLibrary\DbAdapter', [ + 'username' => $config->db->readWriteAdapter->username, + 'password' => $config->db->readWriteAdapter->password, +]); + +// set a default type to use, pointing to an alias +$im->addTypePreference('MyLibrary\DbAdapter', 'dbadapter-readonly'); + +$movieListerRead = $di->get('MyMovieApp\MovieLister'); +$movieListerReadWrite = $di->get('MyMovieApp\MovieLister', [ + 'dbAdapter' => 'dbadapter-readwrite', +]); +``` diff --git a/doc/book/intro.md b/doc/book/intro.md new file mode 100644 index 00000000..c4ce4add --- /dev/null +++ b/doc/book/intro.md @@ -0,0 +1,62 @@ +# Introduction + +## Dependency Injection + +Dependency Injection (here-in called DI) refers to the act of providing +dependencies for an object during instantiation or via a method call. A basic +example looks like this: + +```php +$b = new MovieLister(new MovieFinder()); +``` + +Above, `MovieFinder` is a dependency of `MovieLister`, and `MovieFinder` was +injected into `MovieLister`. + +If +you are not familiar with the concept of DI, here are a couple of great reads: + +- [Matthew Weier O'Phinney's Analogy](http://weierophinney.net/matthew/archives/260-Dependency-Injection-An-analogy.html) +- [Ralph Schindler's Learning DI](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php) +- [Fabien Potencier's Series](http://fabien.potencier.org/article/11/what-is-dependency-injection) on DI + +> ### zend-servicemanager +> +> `Zend\Di` is an example of an Inversion of Control (IoC) container. IoC containers are widely used +> to create object instances that have all dependencies resolved and injected. Dependency Injection +> containers are one form of IoC, but not the only form. +> +> Zend Framework ships with another form of IoC as well, +> [zend-servicemanager](https://zendframework.github.io/zend-servicemanager/). +> Unlike zend-di, zend-servicemanager is code-driven, meaning that you tell it +> what class to instantiate, or provide a factory for the given class. This +> approach offers several benefits: +> +> - Easier to debug (error stacks take you into your factories, not the +> dependency injection container). +> - Easier to setup (write code to instantiate objects, instead of +> configuration). +> - Faster (zend-di has known performance issues due to the approaches used). +> +> Unless you have specific needs for a dependency injection container versus +> more general Inversion of Control, we recommend using zend-servicemanager for +> the above reasons. + +# Dependency Injection Containers + +When your code is written in such a way that all your dependencies are injected +into consuming objects, you might find that the simple act of wiring an object +has gotten more complex. When this becomes the case, and you find that this +wiring is creating more boilerplate code, this makes for an excellent +opportunity to utilize a Dependency Injection Container. + +In it's simplest form, a Dependency Injection Container (here-in called a DiC +for brevity), is an object that is capable of creating objects on request and +managing the "wiring", or the injection of required dependencies, for those +requested objects. Since the patterns that developers employ in writing DI +capable code vary, DiC's are generally either in the form of smallish objects +that suit a very specific pattern, or larger DiC frameworks. + +zend-di is a DiC framework. While for the simplest code there is no +configuration needed, and the use cases are quite simple, zend-di is capable of +being configured to wire these complex use cases diff --git a/doc/book/quick-start.md b/doc/book/quick-start.md new file mode 100644 index 00000000..671be2b2 --- /dev/null +++ b/doc/book/quick-start.md @@ -0,0 +1,138 @@ +# Quick Start + +This quick start is intended to get developers familiar with the concepts of the +zend-di DiC. Generally speaking, code is never as simple as it is inside this +example, so working knowledge of the other sections of the manual is suggested. + +Assume, for a moment, the following application code. It already assumes that +dependencies are injected, and so becomes a good candiate for a DiC. + +```php +namespace MyLibrary +{ + class DbAdapter + { + protected $username = null; + protected $password = null; + + public function __construct($username, $password) + { + $this->username = $username; + $this->password = $password; + } + } +} + +namespace MyMovieApp +{ + class MovieFinder + { + protected $dbAdapter = null; + + public function __construct(\MyLibrary\DbAdapter $dbAdapter) + { + $this->dbAdapter = $dbAdapter; + } + } + + class MovieLister + { + protected $movieFinder = null; + + public function __construct(MovieFinder $movieFinder) + { + $this->movieFinder = $movieFinder; + } + } +} +``` + +With the above code, you find yourself writing the following to wire and utilize +it: + +```php +// $config object is assumed + +$dbAdapter = new MyLibrary\DbAdapter($config->username, $config->password); +$movieFinder = new MyMovieApp\MovieFinder($dbAdapter); +$movieLister = new MyMovieApp\MovieLister($movieFinder); +foreach ($movieLister as $movie) { + // iterate and display $movie +} +``` + +If you are doing this above wiring in each controller or view that wants to list +movies, not only can this become repetitive and boring to write, but also +unmaintainable if you want to swap out one of these dependencies on a wholesale +scale. + +Since this example of code already practices good dependency injection using +constructor injection, it is a great candidate for using zend-di. + +The following demonstrates how to wire the above into a zend-di container: + +```php +// Inside a bootstrap somewhere +$di = new Zend\Di\Di(); +$di->instanceManager()->setParameters('MyLibrary\DbAdapter', [ + 'username' => $config->username, + 'password' => $config->password, +]); + +// Elsewhere: +$movieLister = $di->get('MyMovieApp\MovieLister'); +foreach ($movieLister as $movie) { + // iterate and display $movie +} +``` + +In the above example, we are obtaining a *default instance* of `Zend\Di\Di`. By +'default', we mean that `Zend\\Di\\Di` is constructed with a `DefinitionList` +seeded with a `RuntimeDefinition` (which uses PHP's Reflection API) and an empty +instance manager and no configuration: + +```php +public function __construct( + DefinitionList $definitions = null, + InstanceManager $instanceManager = null, + Configuration $config = null +) { + $this->definitions = ($definitions) ?: new DefinitionList(new Definition\RuntimeDefinition()); + $this->instanceManager = ($instanceManager) ?: new InstanceManager(); + + if ($config) { + $this->configure($config); + } +} +``` + +This means that when `$di->get()` is called, it will be consulting the +`RuntimeDefinition`, which uses Reflection to understand the structure of the +code. Once it knows the structure of the code, it can then know how the +dependencies fit together and how to go about wiring your objects for you. +`Zend\Di\Definition\RuntimeDefinition` will utilize the names of the parameters +in the methods as the class parameter names. This is how both the `username` and +`password` keys are mapped to the first and second parameters, respectively, of +the constructor consuming these named parameters. + +If you were to want to pass in the username and password at call time, this is +achieved by passing them as the second argument to `get()`: + +```php +$di = new Zend\Di\Di(); +$movieLister = $di->get('MyMovieApp\MovieLister', [ + 'username' => $config->username, + 'password' => $config->password +]); +foreach ($movieLister as $movie) { + // iterate and display $movie +} +``` + +It is important to note that when using call time parameters, these parameter +names will be applied to any class that accepts a parameter of such name. + +By calling `$di->get()`, this instance of `MovieLister` will be automatically +shared. This means subsequent calls to `get()` will return the same instance as +previous calls. If you wish to have completely new instances of `MovieLister`, +you can utilize `$di->newInstance()`. diff --git a/doc/book/zend.di.configuration.md b/doc/book/zend.di.configuration.md deleted file mode 100644 index 3230c7e1..00000000 --- a/doc/book/zend.di.configuration.md +++ /dev/null @@ -1,33 +0,0 @@ -# Zend\\Di Configuration - -Most of the configuration for both the setup of Definitions as well as the setup of the Instance -Manager can be attained by a configuration file. This file will produce an array (typically) and -have a particular iterable structure. - -The top two keys are 'definition' and 'instance', each specifying values for respectively, -definition setup and instance manager setup. - -The definition section expects the following information expressed as a PHP array: - -```php -$config = array( - 'definition' => array( - 'compiler' => array(/* @todo compiler information */), - 'runtime' => array(/* @todo runtime information */), - 'class' => array( - 'instantiator' => '', // the name of the instantiator, by default this is __construct - 'supertypes' => array(), // an array of supertypes the class implements - 'methods' => array( - 'setSomeParameter' => array( // a method name - 'parameterName' => array( - 'name', // string parameter name - 'type', // type or null - 'is-required' // bool - ) - ) - - ) - ) - ) -); -``` diff --git a/doc/book/zend.di.definitions.md b/doc/book/zend.di.definitions.md deleted file mode 100644 index 9043edd4..00000000 --- a/doc/book/zend.di.definitions.md +++ /dev/null @@ -1,132 +0,0 @@ -# Zend\\Di Definition - -Definitions are the place where Zend\\Di attempts to understand the structure of the code it is -attempting to wire. This means that if you've written non-ambiguous, clear and concise code; -Zend\\Di has a very good chance of understanding how to wire things up without much added -complexity. - -## DefinitionList - -Definitions are introduced to the Zend\\Di\\Di object through a definition list implemented as -Zend\\Di\\DefinitionList (SplDoublyLinkedList). Order is important. Definitions in the front of the -list will be consulted on a class before definitions at the end of the list. - -> ### Note -Regardless of what kind of Definition strategy you decide to use, it is important that your -autoloaders are already setup and ready to use. - -## RuntimeDefinition - -The default DefinitionList instantiated by Zend\\Di\\Di, when no other DefinitionList is provided, -has as Definition\\RuntimeDefinition baked-in. The RuntimeDefinition will respond to query's about -classes by using Reflection. This Runtime definitions uses any available information inside methods: -their signature, the names of parameters, the type-hints of the parameters, and the default values -to determine if something is optional or required when making a call to that method. The more -explicit you can be in your method naming and method signatures, the easier of a time -Zend\\Di\\Definition\\RuntimeDefinition will have determining the structure of your code. - -This is what the constructor of a RuntimeDefinition looks like: - -```php -public function __construct(IntrospectionStrategy $introspectionStrategy = null, array -$explicitClasses = null) -{ - $this->introspectionStrategy = ($introspectionStrategy) ?: new IntrospectionStrategy(); - if ($explicitClasses) { - $this->setExplicitClasses($explicitClasses); - } -} -``` - -The IntrospectionStrategy object is an object that determines the rules, or guidelines, for how the -RuntimeDefinition will introspect information about your classes. Here are the things it knows how -to do: - -- Whether or not to use Annotations (Annotations are expensive and off by default, read more about -these in the Annotations section) -- Which method names to include in the introspection, by default, the pattern /^set\[A-Z\]{1}\\w\*/ -is registered by default, this is a list of patterns. -- Which interface names represent the interface injection pattern. By default, the pattern -/\\w\*Aware\\w\*/ is registered, this is a list of patterns. - -The constructor for the IntrospectionStrategy looks like this: - -```php -public function __construct(AnnotationManager $annotationManager = null) -{ - $this->annotationManager = ($annotationManager) ?: $this->createDefaultAnnotationManager(); -} -``` - -This goes to say that an AnnotationManager is not required, but if you wish to create a special -AnnotationManager with your own annotations, and also wish to extend the RuntimeDefinition to look -for these special Annotations, this is the place to do it. - -The RuntimeDefinition also can be used to look up either all classes (implicitly, which is default), -or explicitly look up for particular pre-defined classes. This is useful when your strategy for -inspecting one set of classes might differ from those of another strategy for another set of -classes. This can be achieved by using the setExplicitClasses() method or by passing a list of -classes as a second argument to the constructor of the RuntimeDefinition. - -## CompilerDefinition - -The CompilerDefinition is very much similar in nature to the RuntimeDefinition with the exception -that it can be seeded with more information for the purposes of "compiling" a definition. This is -useful when you do not want to be making all those (sometimes expensive) calls to reflection and the -annotation scanning system during the request of your application. By using the compiler, a -definition can be created and written to disk to be used during a request, as opposed to the task of -scanning the actual code. - -For example, let's assume we want to create a script that will create definitions for some of our -library code: - -```php -// in "package name" format -$components = array( - 'My_MovieApp', - 'My_OtherClasses', -); - -foreach ($components as $component) { - $diCompiler = new Zend\Di\Definition\CompilerDefinition; - $diCompiler->addDirectory('/path/to/classes/' . str_replace('_', '/', $component)); - - $diCompiler->compile(); - file_put_contents( - __DIR__ . '/../data/di/' . $component . '-definition.php', - 'toArrayDefinition()->toArray(), true) . ';' - ); -} -``` - -This will create a couple of files that will return an array of the definition for that class. To -utilize this in an application, the following code will suffice: - -```php -protected function setupDi(Application $app) -{ - $definitionList = new DefinitionList(array( - new Definition\ArrayDefinition(include __DIR__ . -'/path/to/data/di/My_MovieApp-definition.php'), - new Definition\ArrayDefinition(include __DIR__ . -'/path/to/data/di/My_OtherClasses-definition.php'), - $runtime = new Definition\RuntimeDefinition(), - )); - $di = new Di($definitionList, null, new Config($this->config->di)); - $di->instanceManager()->addTypePreference('Zend\Di\LocatorInterface', $di); - $app->setLocator($di); -} -``` - -The above code would more than likely go inside your application's or module's bootstrap file. This -represents the simplest and most performant way of configuring your DiC for usage. - -## ClassDefinition - -The idea behind using a ClassDefinition is two-fold. First, you may want to override some -information inside of a RuntimeDefinition. Secondly, you might want to simply define your complete -class's definition with an xml, ini, or php file describing the structure. This class definition can -be fed in via Configuration or by directly instantiating and registering the Definition with the -DefinitionList. - -Todo - example diff --git a/doc/book/zend.di.instance-manager.md b/doc/book/zend.di.instance-manager.md deleted file mode 100644 index cf59fcca..00000000 --- a/doc/book/zend.di.instance-manager.md +++ /dev/null @@ -1,180 +0,0 @@ -# Zend\\Di InstanceManager - -The InstanceManager is responsible for any runtime information associated with the Zend\\Di\\Di DiC. -This means that the information that goes into the instance manager is specific to both how the -particular consuming Application's needs and even more specifically to the environment in which the -application is running. - -## Parameters - -Parameters are simply entry points for either dependencies or instance configuration values. A class -consists of a set of parameters, each uniquely named. When writing your classes, you should attempt -to not use the same parameter name twice in the same class when you expect that that parameters is -used for either instance configuration or an object dependency. This leads to an ambiguous -parameter, and is a situation best avoided. - -Our movie finder example can be further used to explain these concepts: - -```php -namespace MyLibrary -{ - class DbAdapter - { - protected $username = null; - protected $password = null; - public function __construct($username, $password) - { - $this->username = $username; - $this->password = $password; - } - } -} - -namespace MyMovieApp -{ - class MovieFinder - { - protected $dbAdapter = null; - public function __construct(\MyLibrary\DbAdapter $dbAdapter) - { - $this->dbAdapter = $dbAdapter; - } - } - - class MovieLister - { - protected $movieFinder = null; - public function __construct(MovieFinder $movieFinder) - { - $this->movieFinder = $movieFinder; - } - } -} -``` - -In the above example, the class DbAdapter has 2 parameters: username and password; MovieFinder has -one parameter: dbAdapter, and MovieLister has one parameter: movieFinder. Any of these can be -utilized for injection of either dependencies or scalar values during instance configuration or -during call time. - -When looking at the above code, since the dbAdapter parameter and the movieFinder parameter are both -type-hinted with concrete types, the DiC can assume that it can fulfill these object tendencies by -itself. On the other hand, username and password do not have type-hints and are, more than likely, -scalar in nature. Since the DiC cannot reasonably know this information, it must be provided to the -instance manager in the form of parameters. Not doing so will force -$di->get('MyMovieApp\\MovieLister') to throw an exception. - -The following ways of using parameters are available: - -```php -// setting instance configuration into the instance manager -$di->instanceManager()->setParameters('MyLibrary\DbAdapter', array( - 'username' => 'myusername', - 'password' => 'mypassword' -)); - -// forcing a particular dependency to be used by the instance manager -$di->instanceManager()->setParameters('MyMovieApp\MovieFinder', array( - 'dbAdapter' => new MyLibrary\DbAdapter('myusername', 'mypassword') -)); - -// passing instance parameters at call time -$movieLister = $di->get('MyMovieApp\MovieLister', array( - 'username' => $config->username, - 'password' => $config->password -)); - -// passing a specific instance at call time -$movieLister = $di->get('MyMovieApp\MovieLister', array( - 'dbAdapter' => new MyLibrary\DbAdapter('myusername', 'mypassword') -)); -``` - -## Preferences - -In some cases, you might be using interfaces as type hints as opposed to concrete types. Lets assume -the movie example was modified in the following way: - -```php -namespace MyMovieApp -{ - interface MovieFinderInterface - { - // methods required for this type - } - - class GenericMovieFinder implements MovieFinderInterface - { - protected $dbAdapter = null; - public function __construct(\MyLibrary\DbAdapter $dbAdapter) - { - $this->dbAdapter = $dbAdapter; - } - } - - class MovieLister - { - protected $movieFinder = null; - public function __construct(MovieFinderInterface $movieFinder) - { - $this->movieFinder = $movieFinder; - } - } -} -``` - -What you'll notice above is that now the MovieLister type minimally expects that the dependency -injected implements the MovieFinderInterface. This allows multiple implementations of this base -interface to be used as a dependency, if that is what the consumer decides they want to do. As you -can imagine, Zend\\Di, by itself would not be able to determine what kind of concrete object to use -fulfill this dependency, so this type of 'preference' needs to be made known to the instance -manager. - -To give this information to the instance manager, see the following code example: - -```php -$di->instanceManager()->addTypePreference('MyMovieApp\MovieFinderInterface', -'MyMovieApp\GenericMovieFinder'); -// assuming all instance config for username, password is setup -$di->get('MyMovieApp\MovieLister'); -``` - -## Aliases - -In some situations, you'll find that you need to alias an instance. There are two main reasons to do -this. First, it creates a simpler, alternative name to use when using the DiC, as opposed to using -the full class name. Second, you might find that you need to have the same object type in two -separate contexts. This means that when you alias a particular class, you can then attach a specific -instance configuration to that alias; as opposed to attaching that configuration to the class name. - -To demonstrate both of these points, we'll look at a use case where we'll have two separate -DbAdapters, one will be for read-only operations, the other will be for read-write operations: - -> ### Note -Aliases can also have parameters registered at alias time - -```php -// assume the MovieLister example of code from the QuickStart - -$im = $di->instanceManager(); - -// add alias for short naming -$im->addAlias('movielister', 'MyMovieApp\MovieLister'); - -// add aliases for specific instances -$im->addAlias('dbadapter-readonly', 'MyLibrary\DbAdapter', array( - 'username' => $config->db->readAdapter->username, - 'password' => $config->db->readAdapter->password, -)); -$im->addAlias('dbadapter-readwrite', 'MyLibrary\DbAdapter', array( - 'username' => $config->db->readWriteAdapter->username, - 'password' => $config->db->readWriteAdapter->password, -)); - -// set a default type to use, pointing to an alias -$im->addTypePreference('MyLibrary\DbAdapter', 'dbadapter-readonly'); - -$movieListerRead = $di->get('MyMovieApp\MovieLister'); -$movieListerReadWrite = $di->get('MyMovieApp\MovieLister', array('dbAdapter' => -'dbadapter-readwrite')); -``` diff --git a/doc/book/zend.di.introduction.md b/doc/book/zend.di.introduction.md deleted file mode 100644 index 0185b8a1..00000000 --- a/doc/book/zend.di.introduction.md +++ /dev/null @@ -1,51 +0,0 @@ -# Introduction to Zend\\Di - -## Dependency Injection - -Dependency Injection (here-in called DI) is a concept that has been talked about in numerous places -over the web. Simply put, we'll explain the act of injecting dependencies simply with this below -code: - -```php -$b = new MovieLister(new MovieFinder()); -``` - -Above, MovieFinder is a dependency of MovieLister, and MovieFinder was injected into MovieLister. If -you are not familiar with the concept of DI, here are a couple of great reads: [Matthew Weier -O'Phinney's -Analogy](http://weierophinney.net/matthew/archives/260-Dependency-Injection-An-analogy.html), [Ralph -Schindler's Learning -DI](http://ralphschindler.com/2011/05/18/learning-about-dependency-injection-and-php), or [Fabien -Potencier's Series](http://fabien.potencier.org/article/11/what-is-dependency-injection) on DI. - -> ### Note -`Zend\Di` is an example of an Inversion of Control (IoC) container. IoC containers are widely used -to create object instances that have all dependencies resolved and injected. Dependency Injection -containers are one form of IoC -- but not the only form. -Zend Framework 2 ships with another form of IoC as well, -[Zend\\ServiceManager](http://zendframework.github.io/zend-servicemanager/). Unlike `Zend\Di`, The ServiceManager is -code-driven, meaning that you typically tell it what class to instantiate, or provide a factory for -the given class. This approach offers several benefits: -- Easier to debug (error stacks take you into your factories, not the dependency injection -container). -- Easier to setup (write code to instantiate objects, instead of configuration). -- Faster (`Zend\Di` has known performance issues due to the approaches used). -Unless you have specific needs for a dependency injection container versus more general Inversion of -Control, we recommend using `Zend\ServiceManager` for the above reasons. - -## Dependency Injection Containers - -When your code is written in such a way that all your dependencies are injected into consuming -objects, you might find that the simple act of wiring an object has gotten more complex. When this -becomes the case, and you find that this wiring is creating more boilerplate code, this makes for an -excellent opportunity to utilize a Dependency Injection Container. - -In it's simplest form, a Dependency Injection Container (here-in called a DiC for brevity), is an -object that is capable of creating objects on request and managing the "wiring", or the injection of -required dependencies, for those requested objects. Since the patterns that developers employ in -writing DI capable code vary, DiC's are generally either in the form of smallish objects that suit a -very specific pattern, or larger DiC frameworks. - -Zend\\Di is a DiC framework. While for the simplest code there is no configuration needed, and the -use cases are quite simple; for more complex code, Zend\\Di is capable of being configured to wire -these complex use cases diff --git a/doc/book/zend.di.quick-start.md b/doc/book/zend.di.quick-start.md deleted file mode 100644 index 6f4f82e1..00000000 --- a/doc/book/zend.di.quick-start.md +++ /dev/null @@ -1,127 +0,0 @@ -# Zend\\Di Quickstart - -This QuickStart is intended to get developers familiar with the concepts of the Zend\\Di DiC. -Generally speaking, code is never as simple as it is inside this example, so working knowledge of -the other sections of the manual is suggested. - -Assume for a moment, you have the following code as part of your application that you feel is a good -candidate for being managed by a DiC, after all, you are already injecting all your dependencies: - -```php -namespace MyLibrary -{ - class DbAdapter - { - protected $username = null; - protected $password = null; - public function __construct($username, $password) - { - $this->username = $username; - $this->password = $password; - } - } -} - -namespace MyMovieApp -{ - class MovieFinder - { - protected $dbAdapter = null; - public function __construct(\MyLibrary\DbAdapter $dbAdapter) - { - $this->dbAdapter = $dbAdapter; - } - } - - class MovieLister - { - protected $movieFinder = null; - public function __construct(MovieFinder $movieFinder) - { - $this->movieFinder = $movieFinder; - } - } -} -``` - -With the above code, you find yourself writing the following to wire and utilize this code: - -```php -// $config object is assumed - -$dbAdapter = new MyLibrary\DbAdapter($config->username, $config->password); -$movieFinder = new MyMovieApp\MovieFinder($dbAdapter); -$movieLister = new MyMovieApp\MovieLister($movieFinder); -foreach ($movieLister as $movie) { - // iterate and display $movie -} -``` - -If you are doing this above wiring in each controller or view that wants to list movies, not only -can this become repetitive and boring to write, but also unmaintainable if for example you want to -swap out one of these dependencies on a wholesale scale. - -Since this example of code already practices good dependency injection, with constructor injection, -it is a great candidate for using Zend\\Di. The usage is as simple as: - -```php -// inside a bootstrap somewhere -$di = new Zend\Di\Di(); -$di->instanceManager()->setParameters('MyLibrary\DbAdapter', array( - 'username' => $config->username, - 'password' => $config->password -)); - -// inside each controller -$movieLister = $di->get('MyMovieApp\MovieLister'); -foreach ($movieLister as $movie) { - // iterate and display $movie -} -``` - -In the above example, we are obtaining a default instance of Zend\\Di\\Di. By 'default', we mean -that Zend\\Di\\Di is constructed with a DefinitionList seeded with a RuntimeDefinition (uses -Reflection) and an empty instance manager and no configuration. Here is the Zend\\Di\\Di -constructor: - -```php -public function __construct(DefinitionList $definitions = null, InstanceManager $instanceManager = -null, Configuration $config = null) -{ - $this->definitions = ($definitions) ?: new DefinitionList(new Definition\RuntimeDefinition()); - $this->instanceManager = ($instanceManager) ?: new InstanceManager(); - - if ($config) { - $this->configure($config); - } -} -``` - -This means that when $di->get() is called, it will be consulting the RuntimeDefinition, which -uses reflection to understand the structure of the code. Once it knows the structure of the code, it -can then know how the dependencies fit together and how to go about wiring your objects for you. -Zend\\Di\\Definition\\RuntimeDefinition will utilize the names of the parameters in the methods as -the class parameter names. This is how both username and password key are mapped to the first and -second parameter, respectively, of the constructor consuming these named parameters. - -If you were to want to pass in the username and password at call time, this is achieved by passing -them as the second argument of get(): - -```php -// inside each controller -$di = new Zend\Di\Di(); -$movieLister = $di->get('MyMovieApp\MovieLister', array( - 'username' => $config->username, - 'password' => $config->password -)); -foreach ($movieLister as $movie) { - // iterate and display $movie -} -``` - -It is important to note that when using call time parameters, these parameter names will be applied -to any class that accepts a parameter of such name. - -By calling $di->get(), this instance of MovieLister will be automatically shared. This means -subsequent calls to get() will return the same instance as previous calls. If you wish to have -completely new instances of MovieLister, you can utilize $di->newInstance(). diff --git a/doc/bookdown.json b/doc/bookdown.json deleted file mode 100644 index db90b0db..00000000 --- a/doc/bookdown.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "title": "Zend\\Di", - "target": "html/", - "content": [ - "book/zend.di.introduction.md", - "book/zend.di.quick-start.md", - "book/zend.di.definitions.md", - "book/zend.di.instance-manager.md", - "book/zend.di.configuration.md", - "book/zend.di.debugging-and-complex-use-cases.md" - ] -} \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml new file mode 100644 index 00000000..d90ee8c0 --- /dev/null +++ b/mkdocs.yml @@ -0,0 +1,15 @@ +docs_dir: doc/book +site_dir: doc/html +pages: + - index.md + - Intro: intro.md + - "Quick Start": quick-start.md + - Reference: + - Definitions: definitions.md + - "Instance Manager": instance-manager.md + - Configuration: config.md + - "Debugging and Complex Use Cases": debugging-and-complex-use-cases.md +site_name: zend-di +site_description: zend-di +repo_url: 'https://github.com/zendframework/zend-di' +copyright: 'Copyright (c) 2016 Zend Technologies USA Inc.' From 2a83fc02e25190c32ea731e33eabe120a9ba1f89 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 25 Apr 2016 15:55:42 -0500 Subject: [PATCH 4/6] Added documentation build automation --- .gitignore | 2 ++ .travis.yml | 15 ++++++++++++++- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index a7fc91d6..f146c861 100644 --- a/.gitignore +++ b/.gitignore @@ -6,7 +6,9 @@ .*.sw* .*.un~ nbproject +doc/html/ tmp/ +zf-mkdoc-theme/ clover.xml composer.lock diff --git a/.travis.yml b/.travis.yml index 6dd5a7f3..37e2a40d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,16 +4,23 @@ language: php branches: except: - - /^release-.*$/ + - /^release-\d+\.\d+\.\d+.*$/ - /^ghgfk-.*$/ cache: directories: - $HOME/.composer/cache + - $HOME/.local + - zf-mkdoc-theme env: global: - CODE_VERSION="^3.0" + - SITE_URL: https://zendframework.github.io/zend-di + - GH_USER_NAME: "Matthew Weier O'Phinney" + - GH_USER_EMAIL: matthew@weierophinney.net + - GH_REF: github.com/zendframework/zend-di.git + - secure: "nhJ+hLBlGBu5P8udHwGk5eF6mUKubWF5ID+FXHcP86puQzprYIR7Trdv2u4N9M5AKTPKg3Me1QFqR2WgbNyyVWrtyGovCOAFMeZiMBExpNXONoVaAXGlsXCZe6a85Wn54HXeBjuJMKDNlt6LiJqteMf0axyk44h1V/rTbWK5ALKPy2kuILLZgVyEYtwVmrELBduvqR3uHx5PjuGCeJP8LOICuuu7m2JBhWqUBse89vYqhalvXsIButjSrxPmwgSpjOt7zksf//5HwoY1A83+cb6LfR/ZBe1bOgLtfjBBtYyjwL3DsnYPWecfd4qgO69oHT5ZhxOfzLxjSlvtPK0SrH8WEIcFjUnpcGeqyOnydq7HgEC9J6Fnq1VwKLI2VbM/+qQQqvlVDYAQuXvb/YG0sV0x0ad9zEtJ7QPOY8C6ygGm41+lERd39VzQqq5w8IkjXeUAhWzX+ts7w2aIZ3uPYCHoqmvV9DK44/fkmtFHsJU9guDcW1GU/QT91DGVSNMP0qZsZmw6H/kQtDH672GM4xQzv2FgIyqzSY0oggQwtG5y1XkPCr+X2VsSvtTXuihi+ru9g7iqEXU+2aUOyMfB3xnZQ5qiiQUpaatWO/KzRfp/h3b7InPne+nYTrCDfkjJ8N6bypkXv8D6EC/a4zK3XaaMyn0rQ4yPcd99BjHRIOs=" matrix: fast_finish: true @@ -27,6 +34,8 @@ matrix: - php: 5.6 env: - EXECUTE_TEST_COVERALLS=true + - DEPLOY_DOCS="$(if [[ $TRAVIS_BRANCH == 'master' && $TRAVIS_PULL_REQUEST == 'false' ]]; then echo -n 'true' ; else echo -n 'false' ; fi)" + - PATH="$HOME/.local/bin:$PATH" - php: 5.6 env: - CODE_VERSION="^2.6" @@ -58,6 +67,10 @@ script: - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/phpunit --coverage-clover clover.xml ; fi - if [[ $EXECUTE_TEST_COVERALLS != 'true' ]]; then ./vendor/bin/phpunit ; fi - if [[ $EXECUTE_CS_CHECK == 'true' ]]; then ./vendor/bin/php-cs-fixer fix -v --diff --dry-run ; fi + - if [[ $DEPLOY_DOCS == "true" && "$TRAVIS_TEST_RESULT" == "0" ]]; then wget -O theme-installer.sh "https://raw.githubusercontent.com/zendframework/zf-mkdoc-theme/master/theme-installer.sh" ; chmod 755 theme-installer.sh ; ./theme-installer.sh ; fi + +after_success: + - if [[ $DEPLOY_DOCS == "true" ]]; then echo "Preparing to build and deploy documentation" ; ./zf-mkdoc-theme/deploy.sh ; echo "Completed deploying documentation" ; fi after_script: - if [[ $EXECUTE_TEST_COVERALLS == 'true' ]]; then ./vendor/bin/coveralls ; fi From 834695bcf00c04c664ea3142672032929ed2bac5 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 25 Apr 2016 15:56:58 -0500 Subject: [PATCH 5/6] Added CHANGELOG for documentation --- CHANGELOG.md | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0916a3ef..9b71050e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,11 +2,12 @@ All notable changes to this project will be documented in this file, in reverse chronological order by release. -## 2.6.1 - TBD +## 2.6.1 - 2016-04-25 ### Added -- Nothing. +- Adds all existing documentation and publishes it at + https://zendframework.github.io/zend-di/ ### Deprecated @@ -14,15 +15,15 @@ All notable changes to this project will be documented in this file, in reverse ### Removed +- Nothing. + +### Fixed + - [#3](https://github.com/zendframework/zend-di/pull/3) fixes how `InstanceManager::sharedInstancesWithParams()` behaves when multiple calls are made with different sets of parameters (it should return different instances in that situation). -### Fixed - -- Nothing. - ## 2.6.0 - 2016-02-23 ### Added From c7b3d049251febeeb413d05fa44310dd57d60f26 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Mon, 25 Apr 2016 15:58:04 -0500 Subject: [PATCH 6/6] Updated README to point to new documentation. --- README.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/README.md b/README.md index 4f86b9b9..fe27f6a3 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,5 @@ are widely used to create object instances that have all dependencies resolved and injected. Dependency Injection containers are one form of IoC – but not the only form. - - File issues at https://github.com/zendframework/zend-di/issues -- Documentation is at http://framework.zend.com/manual/current/en/index.html#zend-di +- Documentation is at https://zendframework.github.io/zend-di/