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.