Best Practices
This guide presents the best practices for using@brushy/di efficiently and in an organized manner.
For package choice and framework setup (Express, Next.js, React Native), start with Getting Started.
Token Organization
Use Symbols for Tokens
PrefercreateToken("…") or Symbol("…"). Never use plain strings. Strings can collide when two modules use the same name; createToken returns Symbol(description) at runtime, so every token is unique.
Use createToken for Type Inference
createToken is the recommended form of Symbol token: same collision safety, plus inference in register, resolve, useInject, factory dependencies, and useInjectComponent when registering with useValue:
Centralize Token Definition
Keep all tokens in a centralized location:Lifecycle
Choose the Appropriate Lifecycle
- Use
singletonfor shared services (default) - Use
transientfor instances that should not be shared - Use
scopedfor instances that should be shared within a scope (e.g., HTTP request) - Use
immutablefor state managers and instances that should never be invalidated
Use Immutable Lifecycle for State Managers
When working with state management libraries like React Query, Redux, or Zustand, use theimmutable lifecycle to ensure the instance is never invalidated:
Clean Up Resources Properly
Application Structure
Independent Modules
Organize your application into independent modules, each with its own container:Injection in React Components
Prefer using hooks for injection in React components:Component injection (UI)
Register swappable UI on the same container as services. Prefernew Container({ providers: [{ provide, useValue }] }) or container.register(createToken("…"), { useValue: Component }). Resolve in the shell with useInjectComponent:
createToken<T>() is optional. Use it only when the token contract must exist before the implementation (shared tokens.ts). See Component Injection.
Performance
Promise Caching
Use promise caching to avoid multiple API calls:Lazy Loading
UseuseInjectLazy to load heavy dependencies only when needed:
Testability
Test Containers
Create specific containers for tests:Easy Mocking
UseuseValue to inject mocks in tests:
Observability
Monitor the Container
Use the monitor to debug issues:Verify Immutable Integrity
Use theverifyImmutableIntegrity method to ensure immutable instances maintain their identity: