✳️ Телеграм боти. Dependency Injection
Доопрацюємо нашого бота: зробимо різні привітання для звичайних користувачів та адміністраторів.
ID адміністраторів у нас міститься в об’єкті Settings, і виникає проблема — як його отримати у функції обробника.
Це можна зробити кількома способами:
1️⃣ Створити об’єкт Settings як глобальну змінну.
2️⃣ Використати Middleware для Dependency Injection.
3️⃣ Використати Dispatcher для Dependency Injection.
Dependency Injection (DI) — це підхід у програмуванні, який допомагає відокремити створення сутності від її використання.
Глобальні змінні — це не дуже добре. Використання Middleware — більш складний варіант. Тому давайте зосередимося на останньому варіанті.
🔗 aiogram documentation: Dependency Injection
async def main():
settings = Settings(
_env_file=".env",
_env_nested_delimiter='__'
)
async with Bot(token=settings.bot.token.get_secret_value()) as bot:
storage = MemoryStorage()
dp = Dispatcher(storage=storage)
dp.startup.register(startup)
dp.include_router(router)
# Use Dependency Injection
dp["settings"] = settings
await dp.start_polling(bot)
У Dispatcher можна, як у словник, додати власні об'єкти-залежності, щоб потім отримати їх у обробнику як додаткові параметри:
@router.message(Command("start"), F.from_user.as_("from_user"))
async def start_handler(message: Message, from_user: User, settings: Settings):
if from_user.id in settings.bot.admins:
text = f"<i>Hello admin</i> {html.unparse(from_user.first_name)}!"
else:
text = f"<i>Hello</i> {html.unparse(from_user.first_name)}!"
await message.answer(text=text, parse_mode=ParseMode.HTML)
На жаль, Router такої можливості не має. Якщо потрібно ізолювати дані одного роутера від іншого, варто використати Middleware.
#tg_bots
👍1
259 ·