-
-
Notifications
You must be signed in to change notification settings - Fork 802
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added a section on Dependency Injection technology in documentation (#…
…1253) * Added a section on Dependency Injection technology in documentation * Added changelog * Edited comments & titles
- Loading branch information
Showing
3 changed files
with
90 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Added a section on Dependency Injection technology |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
#################### | ||
Dependency injection | ||
#################### | ||
|
||
Dependency injection is a programming technique that makes a class independent of its dependencies. It achieves that by decoupling the usage of an object from its creation. This helps you to follow `SOLID's <https://en.wikipedia.org/wiki/SOLID>`_ dependency inversion and single responsibility principles. | ||
|
||
|
||
How it works in aiogram | ||
======================= | ||
For each update :class:`Dispatcher` passes handling context data. Filters and middleware can also make changes to the context. | ||
|
||
To access contextual data you should specify corresponding keyword parameter in handler or filter. For example, to get :class:`FSMContext` we do it like that: | ||
|
||
.. code-block:: python | ||
@router.message(ProfileCompletion.add_photo, F.photo) | ||
async def add_photo( | ||
message: types.Message, bot: Bot, state: FSMContext | ||
) -> Any: | ||
... # do something with photo | ||
Injecting own dependencies | ||
========================== | ||
|
||
Aiogram provides several ways to complement / modify contextual data. | ||
|
||
The first and easiest way is to simply specify the named arguments in :class:`Dispatcher` initialization, polling start methods or :class:`SimpleRequestHandler` initialization if you use webhooks. | ||
|
||
.. code-block:: python | ||
async def main() -> None: | ||
dp = Dispatcher(..., foo=42) | ||
return await dp.start_polling( | ||
bot, allowed_updates=dp.resolve_used_update_types(), bar="Bazz" | ||
) | ||
Analogy for webhook: | ||
|
||
.. code-block:: python | ||
async def main() -> None: | ||
dp = Dispatcher(..., foo=42) | ||
handler = SimpleRequestHandler(dispatcher=dp, bot=bot, bar="Bazz") | ||
... # starting webhook | ||
:class:`Dispatcher`'s workflow data also can be supplemented by setting values as in a dictionary: | ||
|
||
.. code-block:: python | ||
dp = Dispatcher(...) | ||
dp["eggs"] = Spam() | ||
The middlewares updates the context quite often. | ||
You can read more about them on this page: | ||
|
||
- `Middlewares <middlewares.html>`__ | ||
|
||
The last way is to return a dictionary from the filter: | ||
|
||
.. literalinclude:: ../../../examples/context_addition_from_filter.py | ||
|
||
...or using MagicFilter with :code:`as_()` method. (`Read more <filters/magic_filters.html#get-filter-result-as-handler-argument>`__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
from typing import Any, Dict, Optional, Union | ||
|
||
from aiogram import Router | ||
from aiogram.filters import Filter | ||
from aiogram.types import Message, User | ||
|
||
|
||
router = Router(name=__name__) | ||
|
||
|
||
class HelloFilter(Filter): | ||
def __init__(self, name: Optional[str] = None) -> None: | ||
self.name = name | ||
|
||
async def __call__( | ||
self, | ||
message: Message, | ||
event_from_user: User | ||
# Filters also can accept keyword parameters like in handlers | ||
) -> Union[bool, Dict[str, Any]]: | ||
if message.text.casefold() == "hello": | ||
# Returning a dictionary that will update the context data | ||
return {"name": event_from_user.mention_html(name=self.name)} | ||
return False | ||
|
||
|
||
@router.message(HelloFilter()) | ||
async def my_handler( | ||
message: Message, name: str # Now we can accept "name" as named parameter | ||
) -> Any: | ||
return message.answer( | ||
"Hello, {name}!".format(name=name) | ||
) |