cli/docs/adr/0003-soa-dual-constructor-di.md
Snider 1d73209e89 Add Architecture Decision Records (ADRs) (#312)
* docs: add Architecture Decision Records (ADRs)

Established a system for documenting architectural decisions.
- Created docs/adr directory
- Added ADR template (0000-template.md)
- Established ADR process in docs/adr/README.md
- Documented 4 key existing decisions (0001-0004)
- Integrated ADRs into mkdocs.yml and docs/index.md

* docs: add Architecture Decision Records (ADRs)

Established a system for documenting architectural decisions.
- Created docs/adr directory
- Added ADR template (0000-template.md)
- Established ADR process in docs/adr/README.md
- Documented 4 key existing decisions (0001-0004)
- Integrated ADRs into mkdocs.yml and docs/index.md
- Fixed formatting in pkg/io/local/client.go

* docs: add ADRs and fix auto-merge CI

- Added Architecture Decision Records (ADRs) to docs/adr/
- Integrated ADRs into mkdocs.yml and docs/index.md
- Localized .github/workflows/auto-merge.yml to fix "fatal: not a git repository" error in the reusable workflow by adding explicit --repo context.
2026-02-05 03:43:16 +00:00

1.2 KiB

ADR 0003: Service-Oriented Architecture with Dual-Constructor DI

  • Status: accepted
  • Deciders: Project Maintainers
  • Date: 2025-05-15

Context and Problem Statement

The application consists of many components (config, crypt, workspace, etc.) that depend on each other. We need a consistent way to manage these dependencies and allow for easy testing.

Decision Drivers

  • Testability.
  • Modularity.
  • Ease of service registration.
  • Clear lifecycle management.

Considered Options

  • Global variables/singletons.
  • Dependency Injection (DI) container.
  • Manual Dependency Injection.

Decision Outcome

Chosen option: "Service-Oriented Architecture with Dual-Constructor DI". Each service follows a pattern where it provides a New() constructor for standalone use/testing (static DI) and a Register() function for registration with the Core service container (dynamic DI).

Positive Consequences

  • Easy to unit test services by passing mock dependencies to New().
  • Automatic service discovery and lifecycle management via Core.
  • Decoupled components.

Negative Consequences

  • Some boilerplate required for each service (New and Register).
  • Dependency on pkg/core for Register.