Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 11 additions & 23 deletions docs/adr/0001-dialog-support-is-a-submodule.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,13 @@
# aiogram-dialog support is a submodule, not a separate package

**Decision:** DI for [aiogram-dialog](https://github.com/Tishka17/aiogram_dialog) getters and
callbacks ships as `modern_di_aiogram.dialog` inside this package; we will not publish a separate
`modern-di-aiogram-dialog` distribution, and aiogram-dialog stays a test dependency only.

The alternative — its own repository and PyPI package, matching how every other framework
integration in `modern-python` is packaged — was rejected because aiogram-dialog is not another
entrypoint. It runs *inside* aiogram's dispatch, so the container lifecycle it needs already
exists: `setup_di`'s middleware has built the per-update child container and put it in the
per-update `data`, which is the same dict aiogram-dialog hands getters as `**kwargs` and exposes on
`DialogManager.middleware_data`. What is left to write is a dialog-aware `inject` that locates that
container by call shape. A separate package for that is disproportionate, and it would have to
re-export this package's marker and private child-container key across a distribution boundary,
turning both into public API for the sake of the split.

Keeping it here is what makes the runtime dependency avoidable: the lookup is structural
(duck-typed on `.middleware_data`), `dialog.py` imports nothing from `aiogram_dialog`, and a user
who never touches dialogs pays nothing for the module existing. A separate package would have had
to declare the dependency it exists for.

**Revisit trigger:** dialog support needs setup of its own — its own container lifecycle, its own
middleware, or a runtime import of `aiogram_dialog` — or it grows large enough that its release
cadence stops matching the handler integration's. At that point the boundary is real and a separate
package earns its keep.
DI for [aiogram-dialog](https://github.com/Tishka17/aiogram_dialog) getters and callbacks ships as
`modern_di_aiogram.dialog`, not as its own repository and PyPI distribution the way every other
`modern-di` framework integration is packaged. aiogram-dialog is not another entrypoint: it runs
inside aiogram's dispatch, so `setup_di`'s middleware has already built the per-update child
container and put it in the per-update `data`, which is the same dict aiogram-dialog hands getters
as `**kwargs` and exposes on `DialogManager.middleware_data`. What is left to write is an `inject`
that locates that container by call shape, and a distribution for that would have to re-export this
package's marker and its private container lookup across a release boundary, turning both into
public API for the sake of the split. Staying here is also what keeps the runtime dependency
avoidable: the lookup is duck-typed on `.middleware_data`, `dialog.py` imports nothing from
`aiogram_dialog`, and aiogram-dialog stays a test dependency only.
13 changes: 13 additions & 0 deletions docs/adr/0002-no-auto-inject-for-dialogs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# No `auto_inject` for dialog getters and callbacks

`setup_di(..., auto_inject=True)` sweeps handlers only; dialog getters and callbacks opt in one at a
time with `@modern_di_aiogram.dialog.inject`. The sweep works on handlers because a dispatcher owns
a registry of them, so `_inject_router` can walk `chain_tail` and every observer other than
`update`, rewriting the callback of each handler not already marked injected. Dialogs have no such
registry: getters and callbacks are attributes of `Window` and widget objects, reachable only by
traversing another library's object tree by structure, which is the one thing `dialog.py` avoids so
that it can stay free of a runtime `aiogram_dialog` import
([ADR-0001](0001-dialog-support-is-a-submodule.md)). The payoff would be smaller too: `auto_inject`
exists so an existing bot with many registered handlers needs no decorator added to each, while a
`Window` names its getter and callbacks at their definition site, where `@inject` is already where a
reader is looking.
22 changes: 0 additions & 22 deletions docs/adr/0002-per-update-context-stays-a-literal.md

This file was deleted.

23 changes: 0 additions & 23 deletions docs/adr/0003-no-auto-inject-for-dialogs.md

This file was deleted.

2 changes: 1 addition & 1 deletion docs/agents/domain.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ Single-context repo:
├── CONTEXT.md
├── docs/adr/
│ ├── 0001-dialog-support-is-a-submodule.md
│ └── 0002-per-update-context-stays-a-literal.md
│ └── 0002-no-auto-inject-for-dialogs.md
└── modern_di_aiogram/
```

Expand Down
Loading