Skip to content

Commit 64308d4

Browse files
authored
Merge pull request #5857 from kenjis/fix-docs-factories
docs: improve Factories
2 parents 53a2a2f + 9f2d3ce commit 64308d4

6 files changed

Lines changed: 88 additions & 16 deletions

File tree

user_guide_src/source/concepts/factories.rst

Lines changed: 71 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,84 @@ Factories
99
Introduction
1010
============
1111

12-
Like ``Services``, ``Factories`` are an extension of autoloading that helps keep your code
13-
concise yet optimal, without having to pass around object instances between classes. At its
12+
What are Factories?
13+
-------------------
14+
15+
Like :doc:`./services`, **Factories** are an extension of autoloading that helps keep your code
16+
concise yet optimal, without having to pass around object instances between classes.
17+
18+
At its
1419
simplest, Factories provide a common way to create a class instance and access it from
1520
anywhere. This is a great way to reuse object states and reduce memory load from keeping
1621
multiple instances loaded across your app.
1722

18-
Anything can be loaded by Factories, but the best examples are those classes that are used
23+
Any class can be loaded by Factories, but the best examples are those classes that are used
1924
to work on or transmit common data. The framework itself uses Factories internally, e.g., to
2025
make sure the correct configuration is loaded when using the ``Config`` class.
2126

22-
Take a look at ``Models`` as an example. You can access the Factory specific to ``Models``
23-
by using the magic static method of the Factories class, ``Factories::models()``. Because of
24-
the common path structure for namespaces and folders, Factories know that the model files
25-
and classes are found within **Models**, so you can request a model by its shorthand base name:
27+
Differences from Services
28+
-------------------------
29+
30+
Factories require a concrete class name to instantiate and do not have code to create instances.
31+
32+
So, Factories are not good for creating a complex instance that needs many dependencies,
33+
and you cannot change the class of the instance to be returned.
34+
35+
On the other hand, Services have code to create instances, so it can create a complex instance
36+
that needs other services or class instances. When you get a service, Services require a service name,
37+
not a class name, so the returned instance can be changed without changing the client code.
38+
39+
Example
40+
-------
41+
42+
Take a look at **Models** as an example. You can access the Factory specific to Models
43+
by using the magic static method of the Factories class, ``Factories::models()``.
44+
45+
By default, Factories first searches in the ``App`` namespace for the path corresponding to the magic static method name.
46+
``Factories::models()`` searches the path **Models/**.
47+
48+
In the following code, if you have ``App\Models\UserModel``, the instance will be returned:
2649

2750
.. literalinclude:: factories/001.php
2851

2952
Or you could also request a specific class:
3053

3154
.. literalinclude:: factories/002.php
3255

33-
Next time you ask for the same class anywhere in your code, ``Factories`` will be sure
56+
If you have only ``Blog\Models\UserModel``, the instance will be returned.
57+
But if you have both ``App\Models\UserModel`` and ``Blog\Models\UserModel``,
58+
the instance of ``App\Models\UserModel`` will be returned.
59+
60+
If you want to get ``Blog\Models\UserModel``, you need to disable the option ``preferApp``:
61+
62+
.. literalinclude:: factories/010.php
63+
64+
See :ref:`factories-options` for the details.
65+
66+
Next time you ask for the same class anywhere in your code, Factories will be sure
3467
you get back the instance as before:
3568

3669
.. literalinclude:: factories/003.php
3770

71+
Convenience Functions
72+
=====================
73+
74+
Two shortcut functions for Factories have been provided. These functions are always available.
75+
76+
config()
77+
--------
78+
79+
The first is ``config()`` which returns a new instance of a Config class. The only required parameter is the class name:
80+
81+
.. literalinclude:: factories/008.php
82+
83+
model()
84+
--------
85+
86+
The second function, ``model()`` returns a new instance of a Model class. The only required parameter is the class name:
87+
88+
.. literalinclude:: factories/009.php
89+
3890
Factory Parameters
3991
==================
4092

@@ -79,22 +131,27 @@ Factories Behavior
79131

80132
Options can be applied in one of three ways (listed in ascending priority):
81133

82-
* A configuration class ``Config\Factory`` with a ``$component`` property.
134+
* A configuration class ``Config\Factory`` with a property that matches the name of a component.
83135
* The static method ``Factories::setOptions()``.
84136
* Passing options directly at call time with a parameter.
85137

86138
Configurations
87139
--------------
88140

89141
To set default component options, create a new Config files at **app/Config/Factory.php**
90-
that supplies options as an array property that matches the name of the component. For example,
91-
if you wanted to ensure that all Filters used by your app were valid framework instances,
92-
your **Factory.php** file might look like this:
142+
that supplies options as an array property that matches the name of the component.
143+
144+
For example, if you want to create **Filters** by Factories, the component name wll be ``filters``.
145+
And if you want to ensure that each filter is an instance of a class which implements CodeIgniter's ``FilterInterface``,
146+
your **app/Config/Factory.php** file might look like this:
93147

94148
.. literalinclude:: factories/005.php
95149

96-
This would prevent conflict of an unrelated third-party module which happened to have an
97-
unrelated "Filters" path in its namespace.
150+
Now you can create a filter with code like ``Factories::filters('SomeFilter')``,
151+
and the returned instance will surely be a CodeIgniter's filter.
152+
153+
This would prevent conflict of an third-party module which happened to have an
154+
unrelated ``Filters`` path in its namespace.
98155

99156
setOptions Method
100157
-----------------
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
<?php
22

3-
$widgets = Factories::models('Some\Namespace\Models\WidgetModel');
3+
$users = Factories::models('Blog\Models\UserModel');

user_guide_src/source/concepts/factories/003.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ class SomeOtherClass
44
{
55
public function someFunction()
66
{
7-
$widgets = Factories::models('WidgetModel');
7+
$users = Factories::models('UserModel');
88

99
// ...
1010
}
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
$appConfig = config('App');
4+
5+
// The code above is the same as the code below.
6+
$appConfig = \CodeIgniter\Config\Factories::config('App');
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
$user = model('UserModel');
4+
5+
// The code above is the same as the code below.
6+
$user = \CodeIgniter\Config\Factories::models('UserModel');
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<?php
2+
3+
$widgets = Factories::models('Blog\Models\UserModel', ['preferApp' => false]);

0 commit comments

Comments
 (0)