Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions flutter_modular/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## [5.0.1] - 2022-04-22
- Fix: Inject.get should return instance.

## [5.0.0] - 2022-04-21
- Support Flutter 3.0.0
- [BREAK CHANGE]: Removed `MaterialApp.modular()` and `Cupertino().modular()`.
Expand Down
30 changes: 12 additions & 18 deletions flutter_modular/lib/flutter_modular.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@ import 'src/presenter/navigation/modular_router_delegate.dart';
import 'src/presenter/navigation/router_outlet_delegate.dart';

export 'package:flutter_modular_annotations/flutter_modular_annotations.dart';
export 'package:modular_core/modular_core.dart' show ModularRoute, Disposable, ReassembleMixin;

export 'src/presenter/guards/route_guard.dart';
export 'src/presenter/models/bind.dart';
export 'src/presenter/models/child_route.dart';
export 'src/presenter/models/module_route.dart';
export 'src/presenter/models/wildcard_route.dart';
export 'src/presenter/models/redirect_to_route.dart';
export 'src/presenter/models/modular_args.dart';
export 'src/presenter/models/modular_navigator.dart';
export 'src/presenter/models/module.dart';
export 'src/presenter/models/module_route.dart';
export 'src/presenter/models/redirect_to_route.dart';
export 'src/presenter/models/route.dart';
export 'src/presenter/models/modular_navigator.dart';
export 'src/presenter/widgets/modular_app.dart';
export 'src/presenter/widgets/navigation_listener.dart';
export 'src/presenter/widgets/widget_module.dart';
export 'src/presenter/models/wildcard_route.dart';
export 'src/presenter/navigation/transitions/page_transition.dart';
export 'src/presenter/navigation/transitions/transitions.dart';
export 'src/presenter/widgets/modular_app.dart';
export 'src/presenter/widgets/modular_state.dart';
export 'package:modular_core/modular_core.dart'
show ModularRoute, Disposable, ReassembleMixin;
export 'src/presenter/widgets/navigation_listener.dart';
export 'src/presenter/widgets/widget_module.dart';

IModularBase? _modular;

Expand All @@ -53,11 +53,7 @@ void cleanGlobals() {

extension InjectorExtends on Injector {
/// get arguments
ModularArguments get args => injector
.get<GetArguments>()
.value
.call()
.getOrElse((l) => ModularArguments.empty());
ModularArguments get args => injector.get<GetArguments>().call().getOrElse((l) => ModularArguments.empty());
}

/// It acts as a Nested Browser that will be populated by the children of this route.
Expand Down Expand Up @@ -90,11 +86,9 @@ class RouterOutletState extends State<RouterOutlet> {
void didChangeDependencies() {
super.didChangeDependencies();
final modal = (ModalRoute.of(context)?.settings as ModularPage);
delegate ??= RouterOutletDelegate(modal.route.uri.toString(),
injector.get<ModularRouterDelegate>().value, navigatorKey);
delegate ??= RouterOutletDelegate(modal.route.uri.toString(), injector.get<ModularRouterDelegate>(), navigatorKey);
final router = Router.of(context);
_backButtonDispatcher =
router.backButtonDispatcher!.createChildBackButtonDispatcher();
_backButtonDispatcher = router.backButtonDispatcher!.createChildBackButtonDispatcher();
}

@override
Expand Down
5 changes: 3 additions & 2 deletions flutter_modular/lib/src/infra/services/bind_service_impl.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import 'package:modular_core/modular_core.dart';

import '../../domain/errors/errors.dart';
import '../../shared/either.dart';
import '../../domain/services/bind_service.dart';
import '../../shared/either.dart';

class BindServiceImpl extends BindService {
final Injector injector;
Expand All @@ -17,7 +18,7 @@ class BindServiceImpl extends BindService {
@override
Either<ModularError, BindEntry<T>> getBind<T extends Object>() {
try {
final result = injector.get<T>();
final result = injector.getBind<T>();
return right(result);
} on BindNotFound catch (e, s) {
return left(BindNotFoundException('$T not found.', s));
Expand Down
22 changes: 9 additions & 13 deletions flutter_modular/lib/src/presenter/widgets/widget_module.dart
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import 'package:flutter/widgets.dart';
import 'package:modular_core/modular_core.dart';

import '../../domain/usecases/bind_module.dart';
import '../../domain/usecases/unbind_module.dart';
import '../../flutter_modular_module.dart';
import '../models/bind.dart';
import '../models/module.dart';
import 'package:modular_core/modular_core.dart';

abstract class WidgetModule extends StatelessWidget implements BindContextImpl {
Widget get view;
Expand Down Expand Up @@ -35,12 +36,10 @@ abstract class WidgetModule extends StatelessWidget implements BindContextImpl {
final List<Module> imports = const [];

@override
List<BindEntry> get instanciatedSingletons =>
_fakeModule.instanciatedSingletons;
List<BindEntry> get instanciatedSingletons => _fakeModule.instanciatedSingletons;

@override
void instantiateSingletonBinds(
List<BindEntry<Object>> singletons, Injector injector) {
void instantiateSingletonBinds(List<BindEntry<Object>> singletons, Injector injector) {
_fakeModule.instantiateSingletonBinds(singletons, injector);
}

Expand All @@ -67,8 +66,7 @@ abstract class WidgetModule extends StatelessWidget implements BindContextImpl {
}

@override
void changeBinds(List<BindContract<Object>> newBinds) =>
_fakeModule.changeBinds(newBinds);
void changeBinds(List<BindContract<Object>> newBinds) => _fakeModule.changeBinds(newBinds);

@override
// ignore: invalid_use_of_visible_for_testing_member
Expand All @@ -86,19 +84,17 @@ class ModularProvider<T extends BindContext> extends StatefulWidget {
final BindContext module;
final Widget child;

const ModularProvider({Key? key, required this.module, required this.child})
: super(key: key);
const ModularProvider({Key? key, required this.module, required this.child}) : super(key: key);

@override
_ModularProviderState createState() => _ModularProviderState<T>();
}

class _ModularProviderState<T extends BindContext>
extends State<ModularProvider> {
class _ModularProviderState<T extends BindContext> extends State<ModularProvider> {
@override
void initState() {
super.initState();
injector.get<BindModule>().value.call(widget.module);
injector.get<BindModule>().call(widget.module);
}

@override
Expand All @@ -109,6 +105,6 @@ class _ModularProviderState<T extends BindContext>
@override
void dispose() {
super.dispose();
injector.get<UnbindModule>().value.call<T>();
injector.get<UnbindModule>().call<T>();
}
}
4 changes: 2 additions & 2 deletions flutter_modular/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
name: flutter_modular
description: Smart project structure with dependency injection and route management
version: 5.0.0
version: 5.0.1
homepage: https://github.com/Flutterando/modular

environment:
sdk: ">=2.12.0 <3.0.0"

dependencies:
flutter_modular_annotations: ^0.0.2
modular_core: ">=2.0.0 <3.0.0"
modular_core: ">=2.0.1 <3.0.0"
meta: ">=1.3.0 <2.0.0"
flutter:
sdk: flutter
Expand Down
4 changes: 2 additions & 2 deletions flutter_modular/test/src/flutter_modular_module_test.dart
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import 'package:flutter_modular/src/presenter/modular_base.dart';
import 'package:flutter_modular/src/flutter_modular_module.dart';
import 'package:flutter_modular/src/presenter/modular_base.dart';
import 'package:flutter_test/flutter_test.dart';

void main() {
test('resolver injection (ModularBase)', () {
expect(injector.get<IModularBase>().value, isA<ModularBase>());
expect(injector.get<IModularBase>(), isA<ModularBase>());
});
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import 'package:flutter_modular/flutter_modular.dart';
import 'package:mocktail/mocktail.dart';
import 'package:modular_core/modular_core.dart';
import 'package:flutter_modular/src/shared/either.dart';
import 'package:flutter_modular/src/domain/errors/errors.dart';
import 'package:flutter_modular/src/infra/services/bind_service_impl.dart';
import 'package:flutter_modular/src/shared/either.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mocktail/mocktail.dart';
import 'package:modular_core/modular_core.dart';

import '../../mocks/mocks.dart';

Expand All @@ -14,16 +14,12 @@ void main() {

group('getBind', () {
test('should get bind', () {
when(() => injector.get<String>())
.thenReturn(BindEntry(bind: Bind<String>((i) => ''), value: 'test'));
expect(
service.getBind<String>().map((r) => r.value).getOrElse((left) => ''),
'test');
when(() => injector.getBind<String>()).thenReturn(BindEntry(bind: Bind<String>((i) => ''), value: 'test'));
expect(service.getBind<String>().map((r) => r.value).getOrElse((left) => ''), 'test');
});
test('should throw error not found bind', () {
when(() => injector.get<String>()).thenThrow(BindNotFound('String'));
expect(
service.getBind<String>().fold(id, id), isA<BindNotFoundException>());
when(() => injector.getBind<String>()).thenThrow(BindNotFound('String'));
expect(service.getBind<String>().fold(id, id), isA<BindNotFoundException>());
});
});

Expand All @@ -37,8 +33,7 @@ void main() {
group('releaseScopedBinds', () {
test('should return true', () {
when(() => injector.removeScopedBinds());
expect(
service.releaseScopedBinds().getOrElse((left) => throw left), unit);
expect(service.releaseScopedBinds().getOrElse((left) => throw left), unit);
});
});
}
3 changes: 3 additions & 0 deletions modular_core/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
## 2.0.1 - 2022/05/12
* Fix: Inject.get should return instance

## 2.0.0 - 2022/05/11
* Remove `setDisposeResolver`.
* Apply `BindContract.onDispose` of `modular_interface`.
Expand Down
24 changes: 17 additions & 7 deletions modular_core/lib/src/di/bind_context.dart
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ abstract class BindContextImpl implements BindContext {

@override
@visibleForTesting
List<BindContract> getProcessBinds() => _binds.where((element) => !element.export).toList();
List<BindContract> getProcessBinds() =>
_binds.where((element) => !element.export).toList();
@override
void changeBinds(List<BindContract> newBinds) {
_binds.removeWhere((element) => !element.alwaysSerialized);
Expand All @@ -52,7 +53,9 @@ abstract class BindContextImpl implements BindContext {
return _singletonBinds[type]!.cast<T>();
}

var bind = getProcessBinds().firstWhere((b) => b.factoryFunction is T Function(Injector), orElse: () => BindEmpty());
var bind = getProcessBinds().firstWhere(
(b) => b.factoryFunction is T Function(Injector),
orElse: () => BindEmpty());
if (bind is BindEmpty) {
return null;
}
Expand Down Expand Up @@ -108,16 +111,19 @@ abstract class BindContextImpl implements BindContext {
Future<void> isReady() async {
if (_mutableValue.isReadyFlag) return;
_mutableValue.isReadyFlag = true;
final asyncBindList = getProcessBinds().whereType<AsyncBindContract>().toList();
final asyncBindList =
getProcessBinds().whereType<AsyncBindContract>().toList();
for (var bind in asyncBindList) {
final resolvedBind = await bind.convertToBind();
_binds.insert(0, resolvedBind);
}
}

@mustCallSuper
void instantiateSingletonBinds(List<BindEntry> singletons, Injector injector) {
final filteredList = getProcessBinds().where((bind) => !bind.isLazy && !_containBind(singletons, bind));
void instantiateSingletonBinds(
List<BindEntry> singletons, Injector injector) {
final filteredList = getProcessBinds()
.where((bind) => !bind.isLazy && !_containBind(singletons, bind));
for (final bindElement in filteredList) {
var b = bindElement.factoryFunction(injector);
if (!_singletonBinds.containsKey(b.runtimeType)) {
Expand All @@ -131,15 +137,19 @@ abstract class BindContextImpl implements BindContext {
}

bool _containBind(List<BindEntry> singletons, BindContract bind) {
return singletons.indexWhere((element) => element.bind.factoryFunction == bind.factoryFunction) != -1;
return singletons.indexWhere((element) =>
element.bind.factoryFunction == bind.factoryFunction) !=
-1;
}

Type _getInjectType<B>() {
var foundType = B;

for (var singleton in _singletonBinds.values) {
if (singleton.value is B) {
foundType = _singletonBinds.entries.firstWhere((map) => map.value.value == singleton.value).key;
foundType = _singletonBinds.entries
.firstWhere((map) => map.value.value == singleton.value)
.key;
break;
}
}
Expand Down
20 changes: 14 additions & 6 deletions modular_core/lib/src/di/injector.dart
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import 'package:characters/characters.dart';
import 'package:meta/meta.dart';
import 'reassemble_mixin.dart';
import 'package:modular_interfaces/modular_interfaces.dart';

import 'bind_context.dart';
import 'reassemble_mixin.dart';
import 'resolvers.dart';
import 'package:characters/characters.dart';

class InjectorImpl<T> extends Injector<T> {
final _allBindContexts = <Type, BindContext>{};

@override
BindEntry<B> get<B extends Object>() {
BindEntry<B> getBind<B extends Object>() {
BindEntry<B>? entry;

for (var module in _allBindContexts.values.toList().reversed) {
Expand All @@ -26,9 +27,13 @@ class InjectorImpl<T> extends Injector<T> {
return entry;
}

@override
B get<B extends Object>() => getBind<B>().value;

@override
@mustCallSuper
bool isModuleAlive<B extends BindContext>() => _allBindContexts.containsKey(_getType<B>());
bool isModuleAlive<B extends BindContext>() =>
_allBindContexts.containsKey(_getType<B>());

@override
@mustCallSuper
Expand All @@ -46,7 +51,8 @@ class InjectorImpl<T> extends Injector<T> {
final typeModule = module.runtimeType;
if (!_allBindContexts.containsKey(typeModule)) {
_allBindContexts[typeModule] = module;
(_allBindContexts[typeModule] as BindContextImpl).instantiateSingletonBinds(_getAllSingletons(), this);
(_allBindContexts[typeModule] as BindContextImpl)
.instantiateSingletonBinds(_getAllSingletons(), this);
(_allBindContexts[typeModule] as BindContextImpl).tags.add(tag);
debugPrint("-- $typeModule INITIALIZED");
} else {
Expand Down Expand Up @@ -107,7 +113,9 @@ class InjectorImpl<T> extends Injector<T> {

@override
void updateBinds(BindContext context) {
final key = _allBindContexts.keys.firstWhere((key) => key.toString() == context.runtimeType.toString(), orElse: () => _KeyNotFound);
final key = _allBindContexts.keys.firstWhere(
(key) => key.toString() == context.runtimeType.toString(),
orElse: () => _KeyNotFound);
if (key == _KeyNotFound) {
return;
}
Expand Down
5 changes: 3 additions & 2 deletions modular_core/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: modular_core
description: Smart project structure with dependency injection and route management
version: 2.0.0
version: 2.0.1
homepage: https://github.com/Flutterando/modular

environment:
Expand All @@ -9,7 +9,8 @@ environment:
dependencies:
characters: ">=1.1.0 <2.0.0"
meta: ">=1.3.0 <2.0.0"
modular_interfaces: ">=2.0.0 <3.0.0"
modular_interfaces: ">=2.0.1 <3.0.0"


dev_dependencies:
lints: ^1.0.1
Expand Down
Loading