diff --git a/docs/guide/concept-di-container.md b/docs/guide/concept-di-container.md index f777b40..377a79b 100644 --- a/docs/guide/concept-di-container.md +++ b/docs/guide/concept-di-container.md @@ -76,17 +76,44 @@ $container->get('Foo', [], [ ### PHP Callable Injection In this case, the container will use a registered PHP callable to build new instances of a class. +Each time when [[yii\di\Container::get()]] is called, the corresponding callable will be invoked. The callable is responsible to resolve the dependencies and inject them appropriately to the newly created objects. For example, ```php $container->set('Foo', function () { - return new Foo(new Bar); + $foo = new Foo(new Bar); + // ... other initializations ... + return $foo; }); $foo = $container->get('Foo'); ``` +To hide the complex logic for building a new object, you may use a static class method to return the PHP +callable. For example, + +```php +class FooBuilder +{ + public static function build() + { + return function () { + $foo = new Foo(new Bar); + // ... other initializations ... + return $foo; + }; + } +} + +$container->set('Foo', FooBuilder::build()); + +$foo = $container->get('Foo'); +``` + +As you can see, the PHP callable is returned by the `FooBuilder::build()` method. By doing so, the person +who wants to configure the `Foo` class no longer needs to be aware of how it is built. + Registering Dependencies ------------------------ diff --git a/docs/guide/concept-service-locator.md b/docs/guide/concept-service-locator.md index c820e81..4b69f30 100644 --- a/docs/guide/concept-service-locator.md +++ b/docs/guide/concept-service-locator.md @@ -61,8 +61,10 @@ If you call [[yii\di\ServiceLocator::get()]] with an invalid ID, an exception wi Because service locators are often being created with [configurations](concept-configurations.md), -a writable property named [[yii\di\ServiceLocator::setComponents()|components]] is provided. This allows you to configure and register multiple components at once. The following code shows a configuration array -that can be used to configure an application, while also registering the "db", "cache" and "search" components: +a writable property named [[yii\di\ServiceLocator::setComponents()|components]] is provided. This allows you +to configure and register multiple components at once. The following code shows a configuration array +that can be used to configure a service locator (e.g. an [application](structure-applications.md) with +the "db", "cache" and "search" components: ```php return [ @@ -76,36 +78,40 @@ return [ ], 'cache' => 'yii\caching\ApcCache', 'search' => function () { - return new app\components\SolrService; + $solr = new app\components\SolrService('127.0.0.1'); + // ... other initializations ... + return $solr; }, ], ]; ``` -In complex cases it's a good idea to create extra class to hide configuration complexity: +In the above, there is an alternative way to configure the "search" component. Instead of directly writing a PHP +callback which builds a `SolrService` instance, you can use a static class method to return such a callback, like +shown as below: ```php -class FacebookSDK { - public static function service($config) { - return function() use $config { - // build the object here - return $object; +class SolrServiceBuilder +{ + public static function build($ip) + { + return function () use ($ip) { + $solr = new app\components\SolrService($ip); + // ... other initializations ... + return $solr; }; } } -``` - -It could be used as follows: -```php return [ // ... 'components' => [ // ... - 'facebook' => FacebookSDK::service([ - 'secret' => 'theverysecret', - // ... - ]), + 'search' => SolrServiceBuilder::build('127.0.0.1'), ], ]; ``` + +This alternative approach is most preferable when you are releasing a Yii component which encapsulates some non-Yii +3rd-party library. You use the static method like shown above to represent the complex logic of building the +3rd-party object, and the user of your component only needs to call the static method to configure the component.