Skip to content

Commit 5e76e5d

Browse files
Document new bootstrap process
Signed-off-by: Christoph Wurst <[email protected]>
1 parent 547810e commit 5e76e5d

1 file changed

Lines changed: 80 additions & 18 deletions

File tree

developer_manual/app/bootstrap.rst

Lines changed: 80 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,33 +8,37 @@ might want to register their services to Nextcloud as well. This event is called
88
shall shed some light on how to hook into this with an app.
99

1010

11-
.. _app-php:
11+
.. _application-php:
1212

13-
app.php
14-
-------
13+
The Application class
14+
---------------------
1515

16-
Nextcloud will ``require_once`` every installed and enabled app's ``appinfo/app.php`` file if it exists. The app can use
17-
this file to run registrations of services, event listeners and similar.
16+
The `Application` class is the main entry point of an app. This class is optional but highly recommended if your app needs
17+
to register any services or run some code for every request.
1818

19-
To leverage the advantages of object-oriented programming, it's recommended to put the logic into an :ref:`application-php`
20-
class and query an instance like
19+
20+
Nextcloud will try to autoload the class from the namespace ``\OCA\<App namespace>\AppInfo\Application``, like e.g.
21+
``\OCA\Mail\AppInfo\Application``. The file will therefore be located at ``lib/AppInfo``.
2122

2223
.. code-block:: php
2324
2425
<?php
2526
2627
declare(strict_types=1);
2728
28-
$app = \OC::$server->query(\OCA\MyApp\AppInfo\Application::class);
29-
$app->registerHooks();
29+
namespace OCA\MyApp\AppInfo;
3030
31+
use OCP\AppFramework\App;
3132
32-
.. _application-php:
33+
class Application extends App {
3334
34-
Application
35-
-----------
35+
public function registerHooks(): void {
36+
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\MyApp\Hooks\User', 'deleteUser');
37+
}
3638
37-
An `Application` class shall serve as central initialization point of an app.
39+
}
40+
41+
The class **must** extend ``OCP\AppFramework\App`` and it may optionally implement ``\OCP\AppFramework\Bootstrap\IBootstrap``:
3842

3943
.. code-block:: php
4044
@@ -45,14 +49,72 @@ An `Application` class shall serve as central initialization point of an app.
4549
namespace OCA\MyApp\AppInfo;
4650
4751
use OCP\AppFramework\App;
52+
use OCP\AppFramework\Bootstrap\IBootstrap;
4853
49-
class Application extends App {
54+
class Application extends App implements IBootstrap {
5055
51-
public function registerHooks(): void {
52-
\OCP\Util::connectHook('OC_User', 'pre_deleteUser', 'OCA\MyApp\Hooks\User', 'deleteUser');
56+
public function register(IRegistrationContext $context): void {
57+
// ... registration logic goes here ...
58+
}
59+
60+
public function boot(IBootContext $context): void {
61+
// ... boot logic goes here ...
5362
}
5463
5564
}
5665
57-
.. note:: Nextcloud does not load this class for every request. You should query an instance inside your :ref:`app-php` to
58-
load for every request, if desired.
66+
Bootstrapping process
67+
---------------------
68+
69+
To give a better overview of *when* each of the bootstrapping stages are reached and how they app can interact with them,
70+
this section explains the changes done for Nextcloud 20.
71+
72+
Nextcloud 20 and later
73+
**********************
74+
75+
Nextcloud 20 is the first release with the interface ``\OCP\AppFramework\Bootstrap\IBootstrap``. This interface can be
76+
implemented by apps' Application class to signal that they want to act on the bootstrapping stages. The major difference
77+
between this and the old process is that the boostrapping is not performed in a sequence, but apps register and boot
78+
interleaved. This should ensure that an app that boots can rely on all other apps' registration to be finished.
79+
80+
The overall process is as follows.
81+
82+
1) Each installed and enabled app that has an ``Application`` class class that implements ``IBootstrap``, the ``register``
83+
method will be called. This method receives a context argument via which the app can prime the dependency injection
84+
container and register many other services lazily. The emphsis is on **lazyness**. At this very early stage of the
85+
process lifetime, no other apps nor all of the server components are ready. Therefore the app **must not** try to use
86+
anything except the API provided by the context. That shall ensure that all apps can safely run their registration logic
87+
before any services are queried from the DI container or related code is run.
88+
2) Nextcloud will load groups of certain apps early, like filesystem or session apps, and other later. For this their optional
89+
:ref:`app-php` will be included. As ``app.php`` is deprecated, apps should try not to rely on this step.
90+
3) Nextcloud will query the app's ``Application`` class (again), no matter if it implements ``IBootstrap`` or not.
91+
4) Nextcloud will invoke the ``boot`` method of every ``Application`` instance that implements ``IBootstrap``. At this stage
92+
you may assume that all gegistrations via ``IBootstrap::register`` have been done.
93+
94+
Nextcloud 19 and older
95+
**********************
96+
97+
Nextcloud will load groups of certain apps early, like filesystem or session apps, and other later. For this their optional
98+
:ref:`app-php` will be included. The ``Application`` class is only queried for some requests, so there is no guarantee that
99+
its contstructor will be invoked.
100+
101+
102+
.. _app-php:
103+
104+
app.php (deprecated)
105+
--------------------
106+
107+
Nextcloud will ``require_once`` every installed and enabled app's ``appinfo/app.php`` file if it exists. The app can use
108+
this file to run registrations of services, event listeners and similar.
109+
110+
To leverage the advantages of object-oriented programming, it's recommended to put the logic into an :ref:`Application<application-php>`
111+
class and query an instance like
112+
113+
.. code-block:: php
114+
115+
<?php
116+
117+
declare(strict_types=1);
118+
119+
$app = \OC::$server->query(\OCA\MyApp\AppInfo\Application::class);
120+
$app->registerHooks();

0 commit comments

Comments
 (0)