diff --git a/ios/Podfile.lock b/ios/Podfile.lock index 528ecbb..52e20c4 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -43,4 +43,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c -COCOAPODS: 1.11.2 +COCOAPODS: 1.11.3 diff --git a/lib/data/api/api_config.dart b/lib/data/api/api_config.dart index 35212a4..5fbc7f7 100644 --- a/lib/data/api/api_config.dart +++ b/lib/data/api/api_config.dart @@ -1,3 +1,6 @@ +import 'package:injectable/injectable.dart'; + +@Injectable() class ApiConfig { final String baseUrl; diff --git a/lib/data/preferences/auth_preferences.dart b/lib/data/preferences/auth_preferences.dart index bd271f1..2e272f4 100644 --- a/lib/data/preferences/auth_preferences.dart +++ b/lib/data/preferences/auth_preferences.dart @@ -1,7 +1,10 @@ import 'package:flutter_template/data/model/auth/auth_tokens.dart'; +import 'package:injectable/injectable.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// This class handles the authentication state of the whole app. + +@LazySingleton() class AuthPreferences { AuthPreferences(this._preferences); diff --git a/lib/data/preferences/user_shared_preferences.dart b/lib/data/preferences/user_shared_preferences.dart index f3b09bf..4012d4b 100644 --- a/lib/data/preferences/user_shared_preferences.dart +++ b/lib/data/preferences/user_shared_preferences.dart @@ -2,9 +2,12 @@ import 'dart:convert'; import 'package:flutter_template/domain/entities/user.dart'; import 'package:flutter_template/domain/preferences/user_preferences.dart'; +import 'package:injectable/injectable.dart'; import 'package:shared_preferences/shared_preferences.dart'; /// Store the current authenticated user's basic information. + +@LazySingleton() class UserSharedPreferences extends UserPreferences { UserSharedPreferences(this._preferences); diff --git a/lib/data/services/http_client/dio_http_client.dart b/lib/data/services/http_client/dio_http_client.dart index ab806aa..7f4c92e 100644 --- a/lib/data/services/http_client/dio_http_client.dart +++ b/lib/data/services/http_client/dio_http_client.dart @@ -1,8 +1,11 @@ import 'package:dio/dio.dart'; import 'package:flutter_template/data/services/http_client/http_client.dart'; import 'package:flutter_template/data/services/response_error.dart'; +import 'package:injectable/injectable.dart'; /// Abstraction of the Dio http client class. + +@Injectable(as: HttpClient) class DioHttpClient extends HttpClient { DioHttpClient(this._dio); diff --git a/lib/data/services/http_profile_service.dart b/lib/data/services/http_profile_service.dart index a50d6c7..53447b4 100644 --- a/lib/data/services/http_profile_service.dart +++ b/lib/data/services/http_profile_service.dart @@ -1,5 +1,7 @@ import 'package:flutter_template/domain/services/profile_service.dart'; +import 'package:injectable/injectable.dart'; +@LazySingleton(as: ProfileService) class HttpProfileService extends ProfileService { HttpProfileService(); diff --git a/lib/injection/data_module.dart b/lib/injection/data_module.dart index eda14ef..562a91e 100644 --- a/lib/injection/data_module.dart +++ b/lib/injection/data_module.dart @@ -2,56 +2,31 @@ import 'package:dio/adapter.dart'; import 'package:dio/dio.dart'; import 'package:flutter_template/data/api/api_config.dart'; import 'package:flutter_template/data/interceptor/auth_interceptor.dart'; -import 'package:flutter_template/data/preferences/auth_preferences.dart'; -import 'package:flutter_template/data/preferences/user_shared_preferences.dart'; -import 'package:flutter_template/data/services/http_client/dio_http_client.dart'; -import 'package:flutter_template/data/services/http_client/http_client.dart'; -import 'package:flutter_template/data/services/http_profile_service.dart'; -import 'package:flutter_template/domain/preferences/user_preferences.dart'; -import 'package:flutter_template/domain/services/profile_service.dart'; import 'package:flutter_template/injection/injector.dart'; +import 'package:injectable/injectable.dart'; +import 'package:shared_preferences/shared_preferences.dart'; -class DataModule { - static Future inject() async { - // Prefs - injector.registerLazySingleton( - () => AuthPreferences(injector()), - ); - injector.registerLazySingleton( - () => UserSharedPreferences(injector()), - ); - - // Http - injector.registerFactory(() { - return DioHttpClient(Dio()); - }); - - injector.registerFactory(() { - return DioHttpClient(Dio()); - }); +@module +abstract class DataModule { + @singleton + Future get prefs => SharedPreferences.getInstance(); - injector.registerLazySingleton(() { - final dio = Dio(); - dio.httpClientAdapter = DefaultHttpClientAdapter(); - dio.options.baseUrl = injector.get().apiUrl; - dio.interceptors.add( - AuthInterceptor( - httpClient: injector(), - authPreferences: injector(), - userPreferences: injector(), - refreshTokenHttpClient: injector(), - onTokenExpired: () { - // Handle log out - }, - ), - ); - - return dio; - }); - - // Services - injector.registerLazySingleton( - () => HttpProfileService(), + Dio getDio(ApiConfig apiConfig) { + final dio = Dio(); + dio.httpClientAdapter = DefaultHttpClientAdapter(); + dio.options.baseUrl = apiConfig.apiUrl; + dio.interceptors.add( + AuthInterceptor( + httpClient: injector(), + authPreferences: injector(), + userPreferences: injector(), + refreshTokenHttpClient: injector(), + onTokenExpired: () { + // TODO: Handle log out + }, + ), ); + + return dio; } } diff --git a/lib/injection/dependencies.dart b/lib/injection/dependencies.dart index 4a83d40..6664045 100644 --- a/lib/injection/dependencies.dart +++ b/lib/injection/dependencies.dart @@ -1,7 +1,4 @@ -import 'package:flutter_template/injection/data_module.dart'; import 'package:flutter_template/presentation/app_flavor.dart'; -import 'package:flutter_template/presentation/feature/profile/profile_module.dart'; -import 'package:flutter_template/presentation/routes/app_navigator.dart'; import 'package:flutter_template/presentation/routes/router.gr.dart'; import 'injector.dart'; @@ -10,13 +7,7 @@ class DependencyManager { static Future inject(AppFlavor flavor) async { injector.registerLazySingleton(() => flavor); injector.registerLazySingleton(() => AppRouter()); - injector.registerLazySingleton( - () => AppNavigator(injector.get())); - // App modules - await DataModule.inject(); - - // Feature modules - await ProfileModule.inject(); + await configureDependencies(); } } diff --git a/lib/injection/injector.config.dart b/lib/injection/injector.config.dart new file mode 100644 index 0000000..da683db --- /dev/null +++ b/lib/injection/injector.config.dart @@ -0,0 +1,50 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +// ************************************************************************** +// InjectableConfigGenerator +// ************************************************************************** + +import 'package:dio/dio.dart' as _i7; +import 'package:get_it/get_it.dart' as _i1; +import 'package:injectable/injectable.dart' as _i2; +import 'package:shared_preferences/shared_preferences.dart' as _i12; + +import '../data/api/api_config.dart' as _i4; +import '../data/preferences/auth_preferences.dart' as _i14; +import '../data/preferences/user_shared_preferences.dart' as _i13; +import '../data/services/http_client/dio_http_client.dart' as _i9; +import '../data/services/http_client/http_client.dart' as _i8; +import '../data/services/http_profile_service.dart' as _i11; +import '../domain/services/profile_service.dart' as _i10; +import '../presentation/feature/profile/profile_cubit.dart' as _i15; +import '../presentation/feature/profile/profile_state.dart' as _i16; +import '../presentation/routes/app_navigator.dart' as _i5; +import '../presentation/routes/router.dart' as _i3; +import '../presentation/routes/router.gr.dart' as _i6; +import 'data_module.dart' as _i17; // ignore_for_file: unnecessary_lambdas + +// ignore_for_file: lines_longer_than_80_chars +/// initializes the registration of provided dependencies inside of [GetIt] +_i1.GetIt $initGetIt(_i1.GetIt get, + {String? environment, _i2.EnvironmentFilter? environmentFilter}) { + final gh = _i2.GetItHelper(get, environment, environmentFilter); + final dataModule = _$DataModule(); + gh.factory<_i3.$AppRouter>(() => _i3.$AppRouter()); + gh.factory<_i4.ApiConfig>(() => _i4.ApiConfig(get())); + gh.lazySingleton<_i5.AppNavigator>( + () => _i5.AppNavigator(get<_i6.AppRouter>())); + gh.factory<_i7.Dio>(() => dataModule.getDio(get<_i4.ApiConfig>())); + gh.factory<_i8.HttpClient>(() => _i9.DioHttpClient(get<_i7.Dio>())); + gh.lazySingleton<_i10.ProfileService>(() => _i11.HttpProfileService()); + gh.singletonAsync<_i12.SharedPreferences>(() => dataModule.prefs); + gh.lazySingletonAsync<_i13.UserSharedPreferences>(() async => + _i13.UserSharedPreferences(await get.getAsync<_i12.SharedPreferences>())); + gh.lazySingletonAsync<_i14.AuthPreferences>(() async => + _i14.AuthPreferences(await get.getAsync<_i12.SharedPreferences>())); + gh.factoryParam<_i15.ProfileCubit, _i16.ProfileState?, dynamic>((state, _) => + _i15.ProfileCubit( + profileService: get<_i10.ProfileService>(), state: state)); + return get; +} + +class _$DataModule extends _i17.DataModule {} diff --git a/lib/injection/injector.dart b/lib/injection/injector.dart index ee4f723..dc5032f 100644 --- a/lib/injection/injector.dart +++ b/lib/injection/injector.dart @@ -1,3 +1,13 @@ +import 'package:flutter_template/injection/injector.config.dart'; import 'package:get_it/get_it.dart'; +import 'package:injectable/injectable.dart'; GetIt injector = GetIt.instance; + +@InjectableInit( + initializerName: r'$initGetIt', // default + preferRelativeImports: true, // default + asExtension: false, // default +) +Future configureDependencies() async => $initGetIt(injector); + diff --git a/lib/presentation/feature/profile/profile_cubit.dart b/lib/presentation/feature/profile/profile_cubit.dart index 8f4e77f..7fb8b1b 100644 --- a/lib/presentation/feature/profile/profile_cubit.dart +++ b/lib/presentation/feature/profile/profile_cubit.dart @@ -2,14 +2,15 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_template/domain/services/profile_service.dart'; import 'package:flutter_template/extensions/extensions.dart'; import 'package:flutter_template/presentation/feature/profile/profile_state.dart'; -import 'package:freezed_annotation/freezed_annotation.dart'; +import 'package:injectable/injectable.dart'; +@Injectable() class ProfileCubit extends Cubit { final ProfileService profileService; ProfileCubit({ required this.profileService, - @visibleForTesting ProfileState? state, + @factoryParam ProfileState? state, }) : super(state ?? ProfileState.initial()); void load() async { diff --git a/lib/presentation/feature/profile/profile_module.dart b/lib/presentation/feature/profile/profile_module.dart index ddbb2af..e69de29 100644 --- a/lib/presentation/feature/profile/profile_module.dart +++ b/lib/presentation/feature/profile/profile_module.dart @@ -1,10 +0,0 @@ -import 'package:flutter_template/injection/injector.dart'; -import 'package:flutter_template/presentation/feature/profile/profile_cubit.dart'; - -class ProfileModule { - static Future inject() async { - injector.registerFactory( - () => ProfileCubit(profileService: injector()), - ); - } -} diff --git a/lib/presentation/routes/app_navigator.dart b/lib/presentation/routes/app_navigator.dart index c4a81ec..fdda84b 100644 --- a/lib/presentation/routes/app_navigator.dart +++ b/lib/presentation/routes/app_navigator.dart @@ -1,5 +1,7 @@ import 'package:flutter_template/presentation/routes/router.gr.dart'; +import 'package:injectable/injectable.dart'; +@LazySingleton() class AppNavigator { final AppRouter _appRouter; diff --git a/lib/presentation/routes/router.dart b/lib/presentation/routes/router.dart index 877737d..ea26322 100644 --- a/lib/presentation/routes/router.dart +++ b/lib/presentation/routes/router.dart @@ -1,6 +1,7 @@ import 'package:auto_route/auto_route.dart'; import 'package:flutter_template/presentation/feature/home/home_screen.dart'; import 'package:flutter_template/presentation/feature/splash/splash_screen.dart'; +import 'package:injectable/injectable.dart'; @MaterialAutoRouter( routes: [ @@ -8,4 +9,5 @@ import 'package:flutter_template/presentation/feature/splash/splash_screen.dart' AutoRoute(page: HomeScreen, path: '/home'), ], ) +@Injectable() class $AppRouter {} diff --git a/pubspec.lock b/pubspec.lock index 690e7f1..c2f247a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -203,7 +203,7 @@ packages: name: device_info_plus url: "https://pub.dartlang.org" source: hosted - version: "3.2.2" + version: "3.2.3" device_info_plus_linux: dependency: transitive description: @@ -217,7 +217,7 @@ packages: name: device_info_plus_macos url: "https://pub.dartlang.org" source: hosted - version: "2.2.2" + version: "2.2.3" device_info_plus_platform_interface: dependency: transitive description: @@ -380,6 +380,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + injectable: + dependency: "direct main" + description: + name: injectable + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.3" + injectable_generator: + dependency: "direct dev" + description: + name: injectable_generator + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.3" io: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index b9e8c1a..ae5a7cf 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -46,6 +46,7 @@ dependencies: # Architecture freezed_annotation: 2.0.1 json_annotation: ^4.4.0 + injectable: 1.5.3 get_it: ^7.2.0 auto_route: ^3.2.4 flutter_bloc: ^8.0.1 @@ -55,6 +56,7 @@ dev_dependencies: flutter_test: sdk: flutter build_runner: ^2.1.8 + injectable_generator: 1.5.3 freezed: 2.0.2 json_serializable: ^6.1.5 auto_route_generator: ^3.2.3