modularity_injectable
Optional integration package that connects injectable + GetIt code generation with the Modularity framework.
Note: This package is entirely optional. The core Modularity framework works perfectly with manual
binds/exportsregistration. Use this adapter only if you prefer auto-wiring viainjectable.
Features
GetItBinder— aBinderimplementation backed by scoped GetIt instancesModularityInjectableBridge— helper to invoke injectable-generated functions insidebinds/exportsBinderGetIt— GetIt proxy that resolves dependencies through Modularity rules (local/imports/parent)modularityExportEnv— environment constant to mark dependencies for export
Installation
dependencies:
modularity_injectable: ^0.1.1
dev_dependencies:
build_runner: ^2.4.0
injectable_generator: ^2.4.0
Quick Start
1. Configure your app root
ModularityRoot(
binderFactory: const GetItBinderFactory(),
child: MyApp(),
);
2. Create injectable configuration
// lib/di/auth_injectable.dart
import 'package:get_it/get_it.dart';
import 'package:injectable/injectable.dart';
@InjectableInit(initializerName: 'configureAuthInternal', asExtension: false)
GetIt configureAuthInternal(GetIt getIt) => $initGetIt(getIt);
/// Same generated graph, but we forward the [environmentFilter]
/// so Modularity can limit exports.
@InjectableInit(initializerName: 'configureAuthExports', asExtension: false)
GetIt configureAuthExports(
GetIt getIt, {
EnvironmentFilter? environmentFilter,
}) =>
$initGetIt(
getIt,
environmentFilter: environmentFilter,
);
Why two functions? Both are generated by
injectable. Theexportsvariant simply forwards theenvironmentFilterargument so thatModularityInjectableBridge.configureExportscan injectModularityExportOnlyand keep the public scope limited to explicitly marked services.
3. Annotate your dependencies
@LazySingleton()
class AuthRepositoryImpl implements AuthRepository { ... }
// Pick whichever style you prefer:
// 1) Environment name (works well when you already list multiple envs)
@LazySingleton(env: [modularityExportEnvName])
class AuthService { ... }
// 2) Annotation sugar (for single-purpose modules)
@modularityExportEnv
@LazySingleton()
class AuthController { ... }
4. Wire up your module
class AuthModule extends Module {
@override
void binds(Binder i) {
ModularityInjectableBridge.configureInternal(i, configureAuthInternal);
}
@override
void exports(Binder i) {
ModularityInjectableBridge.configureExports(i, configureAuthExports);
}
}
How It Works
configureInternalregisters all dependencies into the private scopeconfigureExportsregisters only dependencies marked withenv: [modularityExportEnvName](or@modularityExportEnv) into the public scope- This preserves Modularity's strict module boundaries while letting
injectablegenerate the wiring
Manual Alternative
If you prefer explicit registration without code generation, simply use the standard approach:
class AuthModule extends Module {
@override
void binds(Binder i) {
i.singleton<AuthRepository>(() => AuthRepositoryImpl());
}
@override
void exports(Binder i) {
i.singleton<AuthService>(() => AuthService(i.get()));
}
}
See the main Modularity documentation for more details.