# txtxtxtx/tx_di architecture

> Architecture diagram of the GitHub repository txtxtxtx/tx_di, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-05-11). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/txtxtxtx/tx_di
- Repository: https://github.com/txtxtxtx/tx_di

## Overview

1. This repository is a Rust workspace centered on a dependency injection framework called `tx_di`. The architecture is split into three layers: a macro crate that records component metadata at compile time, a core runtime that builds and resolves components, and a set of plugins/examples that show how the framework is embedded into real systems.

2. The framework’s main boundary is between compile time and runtime. `tx-di-macros` expands `#[tx_comp]`, `#[tx_cst]`, and related attributes into component descriptors, dependency lists, scope metadata, and default init hooks. Those generated items are registered into `linkme` distributed slices so the runtime does not need reflection or filesystem scanning.

3. `tx-di-core` is the runtime engine. It owns the component registry, configuration loading, dependency graph resolution, and injection APIs. The key runtime flow is: collect metadata from `linkme`, load global TOML config if present, topologically sort components with Kahn’s algorithm, build singleton/prototype instances into a `DashMap`, then expose them through `BuildContext` and the immutable `App` snapshot.

4. The DI model is intentionally store-based. Components are stored as `Arc`-wrapped values or factories keyed by type identity, and injection is done by type lookup rather than name lookup. This means the primary data flow is from typed metadata to typed instances, with scope decisions handled by the framework rather than by consumers.

5. Configuration is a first-class input to the runtime. Components marked as `conf` are deserialized from TOML sections, and the global `AppAllConfig` object gives access to raw configuration values. In architecture diagrams, config should be shown as an external source feeding `BuildContext` before component construction begins.

6. `tx-di-macros` and `tx-di-core` are tightly coupled but separate by responsibility: macros generate the static description of a component, while core executes the graph. That separation is important because it is what enables compile-time collection with runtime-only resolution, while keeping component authors on a simple attribute-based API.

7. `plugins/` contains reusable integrations built on top of the core DI model. These are not just utilities; they are injectable subsystems that become part of the dependency graph through the same `linkme` registration mechanism. The important plugins are `tx_di_log` for tracing-based logging, `tx_di_axum` for HTTP hosting, `tx_di_sip` for SIP transport and routing, `tx_di_gb28181` for GB28181 server behavior, `tx_di_gb28181_client` for device emulation, `tx_di_can` for CAN/CANFD communication, and small support crates such as `tx_di_toasty`.

8. `tx_di_axum` is the web boundary. It wraps an Axum/Tokio server and exposes HTTP concerns such as health checks, CORS, static files, and middleware. In the architecture, it sits at the edge, consuming DI-managed config and services, then serving requests into the rest of the application.

9. `tx_di_sip` is the protocol boundary for SIP. It provides the transport/listener and message routing layer that the GB28181 plugins build upon. Architecturally, it turns network SIP traffic into handler dispatch, and it is the bridge between raw UDP/TCP packets and higher-level domain logic.

10. `tx_di_gb28181` and `common/tx_gb28181` form the main domain subsystem for GB28181-2022. The common crate holds shared protocol types and parsers/encoders for SIP, SDP, XML, device/channel models, and events. The server plugin adds registration, catalog queries, INVITE/playback flows, PTZ control, alarms, and media backend integration. The client plugin simulates a device side of the same protocol. The shared library is the contract boundary between both sides.

11. Media handling in the GB28181 server is separated from signaling. Under `plugins/tx_di_gb28181/src/media`, the code abstracts different streaming backends such as ZLMediaKit, MediaMTX, or a null backend. This means signaling logic can request media resources without being coupled to a specific streaming server implementation.

12. `tx_di_can` is a distinct embedded/diagnostics subsystem. It abstracts CAN and CANFD adapters, ISO-TP segmentation, UDS diagnostic messaging, and flash/programming workflows. Unlike the web/SIP pieces, this plugin represents a hardware-protocol edge that can also be injected and wired through the same DI mechanism.

13. The `examples/` directory shows two end-to-end applications built from the same primitives. `gb28181_admin` combines a backend API and Vue UI for administration, sessions, devices, and SSE updates. `gb_cams` models a camera fleet with device management, event APIs, and a web UI. These examples are important because they show how the framework is intended to assemble into complete systems.

14. Overall, the architecture is: component definitions in user crates and plugins → compile-time metadata generation via proc macros → link-time registration via `linkme` → runtime graph construction and configuration loading in `tx-di-core` → edge services such as Axum, SIP, GB28181, or CAN consuming the injected components. This is the main shape to capture in a diagram.

Main entry points: [`tx-di-core/src/lib.rs`](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/lib.rs) (tx-di-core), [`plugins/tx_di_gb28181/src/lib.rs`](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181/src/lib.rs) (GB28181 server), [`tx-di-core/src/di/comp/config.rs`](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/comp/config.rs) (App config), [`tx-di-core/src/di/common/mod.rs`](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/common/mod.rs) (BuildContext)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_group_compile["Compile time"]
  node_node_macros{{"tx-di-macros<br/>proc-macro crate<br/>[lib.rs]"}}
  node_node_compile_meta["Static metadata<br/>generated descriptors"]
  node_node_linkme(("linkme registry<br/>distributed slices"))
end

subgraph group_group_runtime["Runtime core"]
  node_node_core{{"tx-di-core<br/>runtime crate<br/>[lib.rs]"}}
  node_node_registry[("Registry<br/>component index<br/>[mod.rs]")]
  node_node_config["App config<br/>config loading<br/>[config.rs]"]
  node_node_resolver["Graph resolver<br/>toposort engine<br/>[mod.rs]"]
  node_node_buildctx["BuildContext<br/>build context<br/>[mod.rs]"]
  node_node_app["App snapshot<br/>immutable runtime<br/>[lib.rs]"]
  node_node_store[("Instance store<br/>DashMap cache<br/>[r.rs]")]
end

subgraph group_group_plugins["Plugins"]
  node_node_axum["tx_di_axum<br/>HTTP plugin<br/>[lib.rs]"]
  node_node_sip["tx_di_sip<br/>SIP plugin<br/>[lib.rs]"]
  node_node_gb_server["GB28181 server<br/>server plugin<br/>[lib.rs]"]
  node_node_gb_client["GB28181 client<br/>device plugin<br/>[lib.rs]"]
  node_node_gb_media["Media backends<br/>media adapters<br/>[mod.rs]"]
  node_node_can["tx_di_can<br/>embedded plugin<br/>[lib.rs]"]
  node_node_log["tx_di_log<br/>logging plugin<br/>[lib.rs]"]
end

subgraph group_group_examples["Examples"]
  node_node_admin["gb28181_admin<br/>full app<br/>[main.rs]"]
  node_node_cams["gb_cams<br/>full app<br/>[main.rs]"]
end

subgraph group_group_domain["Shared domain"]
  node_node_common["tx_gb28181<br/>shared protocol crate<br/>[lib.rs]"]
end

node_node_macros -->|"expands"| node_node_compile_meta
node_node_compile_meta -->|"registers"| node_node_linkme
node_node_linkme -->|"feeds"| node_node_core
node_node_core -->|"owns"| node_node_registry
node_node_core -->|"loads"| node_node_config
node_node_core -->|"resolves"| node_node_resolver
node_node_resolver -->|"builds with"| node_node_buildctx
node_node_buildctx -->|"populates"| node_node_store
node_node_buildctx -->|"freezes into"| node_node_app
node_node_store -->|"serves"| node_node_app
node_node_config -->|"configures"| node_node_axum
node_node_config -->|"configures"| node_node_sip
node_node_config -->|"configures"| node_node_gb_server
node_node_config -->|"configures"| node_node_can
node_node_sip -->|"supports"| node_node_gb_server
node_node_common -->|"contracts"| node_node_gb_server
node_node_common -->|"contracts"| node_node_gb_client
node_node_gb_server -->|"requests"| node_node_gb_media
node_node_axum -->|"serves"| node_node_admin
node_node_gb_server -->|"powers"| node_node_admin
node_node_gb_client -->|"powers"| node_node_cams
node_node_can -.->|"injects into"| node_node_core
node_node_axum -.->|"injects into"| node_node_core
node_node_gb_server -.->|"injects into"| node_node_core
node_node_gb_client -.->|"injects into"| node_node_core
node_node_log -.->|"injects into"| node_node_core

click node_node_macros "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-macros/src/lib.rs"
click node_node_core "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/lib.rs"
click node_node_registry "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/comp/mod.rs"
click node_node_config "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/comp/config.rs"
click node_node_resolver "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/mod.rs"
click node_node_buildctx "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/common/mod.rs"
click node_node_app "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/lib.rs"
click node_node_store "https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/common/r.rs"
click node_node_axum "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_axum/src/lib.rs"
click node_node_sip "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_sip/src/lib.rs"
click node_node_gb_server "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181/src/lib.rs"
click node_node_gb_client "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181_client/src/lib.rs"
click node_node_gb_media "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181/src/media/mod.rs"
click node_node_can "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_can/src/lib.rs"
click node_node_log "https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_log/src/lib.rs"
click node_node_common "https://github.com/txtxtxtx/tx_di/blob/master/common/tx_gb28181/src/lib.rs"
click node_node_admin "https://github.com/txtxtxtx/tx_di/blob/master/examples/gb28181_admin/src/main.rs"
click node_node_cams "https://github.com/txtxtxtx/tx_di/blob/master/examples/gb_cams/src/main.rs"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_node_macros,node_node_compile_meta,node_node_linkme toneBlue
class node_node_core,node_node_registry,node_node_config,node_node_resolver,node_node_buildctx,node_node_app,node_node_store toneAmber
class node_node_axum,node_node_sip,node_node_gb_server,node_node_gb_client,node_node_gb_media,node_node_can,node_node_log toneMint
class node_node_admin,node_node_cams toneRose
class node_node_common toneIndigo
```

## Components

### Compile time

Macro expansion and static component metadata generation.

- [tx-di-macros](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-macros/src/lib.rs): proc-macro crate · Expands component attributes into descriptors, dependency lists, scope metadata, and init hooks. · `tx-di-macros/src/lib.rs`
- **Static metadata**: generated descriptors · Component definitions registered into distributed slices for runtime discovery.
- **linkme registry**: distributed slices · Link-time collection point for component metadata without reflection or scanning.

### Runtime core

Dependency graph construction, config loading, and instance resolution.

- [tx-di-core](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/lib.rs): runtime crate · Builds the dependency graph, loads config, and resolves injectable components. · `tx-di-core/src/lib.rs`
- [Registry](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/comp/mod.rs): component index · Holds registered component definitions and type-keyed lookup state. · `tx-di-core/src/di/comp/mod.rs`
- [App config](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/comp/config.rs): config loading · Loads global TOML config and exposes raw application configuration. · `tx-di-core/src/di/comp/config.rs`
- [Graph resolver](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/mod.rs): toposort engine · Sorts dependencies with Kahn-style resolution and computes build order. · `tx-di-core/src/di/mod.rs`
- [BuildContext](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/common/mod.rs): build context · Construction-time context that supplies config and dependency access to factories. · `tx-di-core/src/di/common/mod.rs`
- [App snapshot](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/lib.rs): immutable runtime · Frozen application state exposing built singletons and factories for lookup. · `tx-di-core/src/lib.rs`
- [Instance store](https://github.com/txtxtxtx/tx_di/blob/master/tx-di-core/src/di/common/r.rs): DashMap cache · Stores Arc-wrapped singletons and factory outputs keyed by type identity. · `tx-di-core/src/di/common/r.rs`

### Plugins

Injectable subsystems built on the DI model.

- [tx_di_axum](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_axum/src/lib.rs): HTTP plugin · Axum/Tokio edge for health checks, CORS, static files, and middleware. · `plugins/tx_di_axum/src/lib.rs`
- [tx_di_sip](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_sip/src/lib.rs): SIP plugin · Listener, sender, and handler routing for SIP traffic. · `plugins/tx_di_sip/src/lib.rs`
- [GB28181 server](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181/src/lib.rs): server plugin · Registration, catalog, INVITE/playback, PTZ, alarms, and media coordination. · `plugins/tx_di_gb28181/src/lib.rs`
- [GB28181 client](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181_client/src/lib.rs): device plugin · Emulates a GB28181 device-side client and device handlers. · `plugins/tx_di_gb28181_client/src/lib.rs`
- [Media backends](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_gb28181/src/media/mod.rs): media adapters · Abstracts ZLM, MediaMTX, and null streaming backends. · `plugins/tx_di_gb28181/src/media/mod.rs`
- [tx_di_can](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_can/src/lib.rs): embedded plugin · CAN/CANFD adapters, ISO-TP, UDS diagnostics, and flash workflows. · `plugins/tx_di_can/src/lib.rs`
- [tx_di_log](https://github.com/txtxtxtx/tx_di/blob/master/plugins/tx_di_log/src/lib.rs): logging plugin · Tracing-oriented logging component for DI-managed systems. · `plugins/tx_di_log/src/lib.rs`

### Examples

End-to-end applications assembled from the framework.

- [gb28181_admin](https://github.com/txtxtxtx/tx_di/blob/master/examples/gb28181_admin/src/main.rs): full app · Backend API and Vue UI for administration, sessions, devices, and SSE. · `examples/gb28181_admin/src/main.rs`
- [gb_cams](https://github.com/txtxtxtx/tx_di/blob/master/examples/gb_cams/src/main.rs): full app · Camera-fleet application with device management, event APIs, and web UI. · `examples/gb_cams/src/main.rs`

### Shared domain

Protocol and model types shared across GB28181 components.

- [tx_gb28181](https://github.com/txtxtxtx/tx_di/blob/master/common/tx_gb28181/src/lib.rs): shared protocol crate · Shared SIP/SDP/XML/device/event types and parsers for GB28181. · `common/tx_gb28181/src/lib.rs`

## Connections

- tx-di-macros → Static metadata: expands · Macro expansion produces component descriptors and hooks.
- Static metadata → linkme registry: registers · Generated metadata is placed into distributed slices.
- linkme registry → tx-di-core: feeds · Runtime discovers all components through link-time registration.
- tx-di-core → Registry: owns · Core maintains the component registry.
- tx-di-core → App config: loads · Core loads global configuration before construction.
- tx-di-core → Graph resolver: resolves · Core computes dependency order and build plan.
- Graph resolver → BuildContext: builds with · Resolution drives construction through BuildContext.
- BuildContext → Instance store: populates · Factories and singletons are inserted into the instance store.
- BuildContext → App snapshot: freezes into · Completed instances become an immutable app snapshot.
- Instance store → App snapshot: serves · The App exposes typed lookup from the stored instances.
- App config → tx_di_axum: configures · HTTP plugin consumes DI-managed config and services.
- App config → tx_di_sip: configures · SIP transport and routing are configured from runtime config.
- App config → GB28181 server: configures · GB28181 server behavior is driven by loaded config.
- App config → tx_di_can: configures · CAN plugin uses TOML-backed configuration.
- tx_di_sip → GB28181 server: supports · GB28181 server builds on SIP transport and routing.
- tx_gb28181 → GB28181 server: contracts · Shared protocol types define the server-side domain contract.
- tx_gb28181 → GB28181 client: contracts · Shared protocol types define the client-side domain contract.
- GB28181 server → Media backends: requests · Server delegates streaming backend selection and media operations.
- tx_di_axum → gb28181_admin: serves · Example admin app exposes HTTP endpoints and UI-backed workflows.
- GB28181 server → gb28181_admin: powers · Admin app uses GB28181 server capabilities and state.
- GB28181 client → gb_cams: powers · Camera example uses the device-side GB28181 client.
- tx_di_can → tx-di-core: injects into · Plugin is wired through the same DI runtime mechanism.
- tx_di_axum → tx-di-core: injects into · HTTP edge is assembled as a DI-managed subsystem.
- GB28181 server → tx-di-core: injects into · GB28181 server participates in the same component graph.
- GB28181 client → tx-di-core: injects into · Client plugin is registered and resolved by the core.
- tx_di_log → tx-di-core: injects into · Logging plugin is added as a DI component.
