Skip to main content

Design Patterns

Dependency Inversion

Decouple high-level modules from low-level implementations.

final databaseToken = provide<Database>();
final userServiceToken = provide<UserService>((inject) =>
UserServiceImpl(inject(databaseToken))
);

Strategy

Swap behavior per environment using provider overrides.

final paymentProcessorToken = provide<PaymentProcessor>();

final prod = WiretapContext(providers: [
paymentProcessorToken.provideOverride((_) => StripeProcessor()),
]);

final test = WiretapContext(providers: [
paymentProcessorToken.provideOverride((_) => MockProcessor()),
]);

Service Locator

Centralize service discovery via a composed context.

final serviceLocator = WiretapContext(providers: [
loggerToken.provideOverride((_) => FileLogger()),
cacheToken.provideOverride((_) => RedisCache()),
configToken.provideOverride((_) => AppConfig.fromEnvironment()),
]).inject;

Aggregated Strategy (Plugins)

Collect multiple implementations for plugin architectures.

final pluginToken = provideCollection<Plugin>();
final context = WiretapContext(providers: [
pluginToken.provideAdditional((_) => [AuthPlugin(), LoggingPlugin()]),
pluginToken.provideAdditional((_) => [MetricsPlugin()]),
]);

final plugins = context.inject(pluginToken);