Skip to content

Commit

Permalink
Updated docs
Browse files Browse the repository at this point in the history
  • Loading branch information
abmmhasan committed Jan 27, 2025
1 parent b3ff9b8 commit 80bd127
Show file tree
Hide file tree
Showing 5 changed files with 578 additions and 633 deletions.
189 changes: 130 additions & 59 deletions docs/di/attribute.rst
Original file line number Diff line number Diff line change
@@ -1,59 +1,130 @@
.. _di.attribute:

==========
Attribute
==========

Using **attribute** we can pass data into property or method if related options are enabled. For this there is
some pre-requisite as given below:

For method attribute,

* ``methodAttributes`` parameter in ``setOptions()`` should be set to true
* On method or arguments, attributes should be marked using ``Infocyph\InterMix\DI\Attribute\Infuse()`` class

For property attribute

* ``propertyAttributes`` parameter in ``setOptions()`` should be set to true
* Attributes should be marked using ``Infocyph\InterMix\DI\Attribute\Infuse()`` class

Method attribute
----------------

In case of method attribute, assignment is possible in 2 ways:

* on argument

.. code:: php
// foo will be resolved into $foo
function example(#[Infuse('foo')] string $foo) {}
* on method (with DocBlock)

.. code:: php
// foo will be resolved into $foo
#[Infuse(foo: 'data')]
function example(string $foo) {}
Property attribute
------------------

In case of property 2 possible ways:

* Inject class

.. code:: php
// AClass will be resolved and injected
#[Infuse]
private AClass $aClassInstance;
* Same as Method attribute

.. code:: php
// definition will be injected (db.host)
#[Infuse('db.host')]
private string $aClassInstance;
.. _di.attribute:

==========
Attributes
==========

InterMix supports **property** and **method** injection via the ``Infuse`` attribute
(:php:class:`Infocyph\\InterMix\\DI\\Attribute\\Infuse`). This lets you annotate class
properties or method parameters so the container can **inject** values or definitions
automatically.

------------

Prerequisites
------------

- **Method Attributes**:
Set ``methodAttributes = true`` in :php:meth:`Infocyph\\InterMix\\DI\\Managers\\OptionsManager.setOptions`.
- **Property Attributes**:
Set ``propertyAttributes = true`` in :php:meth:`Infocyph\\InterMix\\DI\\Managers\\OptionsManager.setOptions`.

Once enabled, the container checks for the :php:class:`Infocyph\\InterMix\\DI\\Attribute\\Infuse`
attributes and resolves them accordingly during:

- **Method resolution** (constructor or user-registered method).
- **Property resolution** (if property injection is allowed).

-----------------
Method Attributes
-----------------

Method attributes can appear in **two** ways:

1. **On Individual Parameters**:

.. code-block:: php
use Infocyph\InterMix\DI\Attribute\Infuse;
class MyService
{
public function example(
#[Infuse('foo')] string $foo
) {
// 'foo' is looked up in the container definitions or environment overrides
}
}
If no explicit parameter supply is found for ``$foo``, it tries the container definitions
under ``'foo'``.

2. **On the Entire Method** with key-value pairs:

.. code-block:: php
use Infocyph\InterMix\DI\Attribute\Infuse;
class MyService
{
#[Infuse(foo: 'data')]
public function example(string $foo) {
// $foo defaults to 'data' if no other supply or definitions override it
}
}
The container merges these attribute-provided values with any user-supplied or
definition-based parameters.

------------------
Property Attribute
------------------

When **propertyAttributes** is true, InterMix can inject properties via
``#[Infuse(...)]``:

1. **Injecting a Class**:

.. code-block:: php
use Infocyph\InterMix\DI\Attribute\Infuse;
class Example
{
#[Infuse]
private AClass $aClassInstance;
// The container resolves AClass automatically if injection is enabled.
}
2. **Injecting a Definition or Function**:

.. code-block:: php
use Infocyph\InterMix\DI\Attribute\Infuse;
class Example
{
#[Infuse('db.host')]
private string $host;
// 'db.host' is fetched from container definitions
#[Infuse(strtotime: 'last monday')]
private int $timestamp;
// calls strtotime('last monday') and injects the result
}
**Note**: If you also provided property values via
:php:meth:`Infocyph\\InterMix\\DI\\Managers\\RegistrationManager.registerProperty()`,
that user-supplied data **overrides** the attribute approach.

----

Enabling Attributes
-------------------

Just call:

.. code-block:: php
$container->options()
->setOptions(
injection: true,
methodAttributes: true,
propertyAttributes: true
);
Now any :php:class:`Infuse` attributes on methods/parameters/properties
are honored when the container builds or calls those classes.

**Tip**: If you only want method injection, set just ``methodAttributes=true``
and leave property as false, or vice versa.
108 changes: 72 additions & 36 deletions docs/di/cache.rst
Original file line number Diff line number Diff line change
@@ -1,36 +1,72 @@
.. _di.cache:

==================
Definition Caching
==================

Everytime you execute the library it will compile the definition on-demand basis & In many cases it may/will consume execution
time & memory. To mitigate this, InterMix supports definition caching.

For this our library uses `Symphony Cache Library <https://symfony.com/doc/current/components/cache.html>`__. Check the link
for more details.

InterMix have 2 methods dedicated to this caching mechanism.

enableDefinitionCache(CacheInterface $cache)
--------------------------------------------

Execute this function to enable definition caching. As it uses `Symphony Cache Library <https://symfony.com/doc/current/components/cache.html>`__
you can pass any Adapter from this library.

.. code:: php
use Symfony\Component\Cache\Adapter\FilesystemAdapter; // we used FilesystemAdapter
$cache = new FilesystemAdapter();
$container->enableDefinitionCache($cache);
cacheAllDefinitions(bool $forceClearFirst = false)
--------------------------------------------------

Set this in a command to pre cache all the definitions. Pass `true` as parameter to force the re-cache. Can only be
used after setting `enableDefinitionCache()`

.. code:: php
$container->cacheAllDefinitions();
.. _di.cache:

==================
Definition Caching
==================

InterMix can **cache** definitions so repeated calls don't re-reflect or re-resolve them,
**improving performance** across repeated usage.

It uses `Symfony Cache <https://symfony.com/doc/current/components/cache.html>`__
(``CacheInterface``). You can pass any Symfony cache adapter (e.g., FilesystemAdapter, RedisAdapter).

---------------------------------------
enableDefinitionCache(CacheInterface $cache)
---------------------------------------

Enables definition caching:

.. code-block:: php
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
$cache = new FilesystemAdapter();
$container->definitions()
->enableDefinitionCache($cache);
**After this**, any definitions the container resolves are stored in that cache.
If you remove or change a definition, or want to re-build them, see below.

-------------------------------------------
cacheAllDefinitions(bool $forceClearFirst)
-------------------------------------------

Preemptively resolve **all** container definitions, storing them in cache:

.. code-block:: php
$container->definitions()
->cacheAllDefinitions($forceClearFirst = false);
- ``$forceClearFirst = true``: Clears the container’s keys from the cache first, ensuring
a fresh build.

**Flow**:

1. For each definition (in ``functionReference``), the container calls ``resolveByDefinition($id)``.
2. The resulting object/value is cached in Symfony cache **and** in local
:php:meth:`resolvedDefinition`.

Hence next time you call:

.. code-block:: php
$container->get('someDefinition');
the container loads it instantly from cache. This can **significantly** reduce overhead in
production if you have complex definitions or reflection usage.

------------------
Lazy vs. Immediate
------------------

InterMix also supports **lazy loading** for definitions, which can be combined with caching.
If lazy loading is on (``enableLazyLoading(true)``) but you also want a definition to skip lazy
and be resolved eagerly, you can:

- **Bind a user closure** directly. (User closures are always resolved **immediately** for
clarity—thus caching the result if caching is on.)
- Or call ``cacheAllDefinitions()`` so everything is forced into cache right away.

**Either way**, the container ensures you do not re-resolve the same definition repeatedly,
thanks to caching.
Loading

0 comments on commit 80bd127

Please sign in to comment.