jonsamwell / flutter_simple_dependency_injection

A super simple dependency injection implementation for flutter that behaviours like any normal IOC container and does not rely on mirrors
MIT License
94 stars 8 forks source link

A value of type 'HttpClient' can't be assigned to a variable of type 'IClient'. #12

Closed Dr-Legend closed 4 years ago

Dr-Legend commented 4 years ago

getting this error whenever i build for web using "flutter build web" ➜ pressy_admin git:(master) ✗ flutter build web Running "flutter pub get" in pressy_admin... 0.6s

0 Dart2JSTarget.build (package:flutter_tools/src/build_system/targets/web.dart:154:7)

#1 _BuildInstance._invokeInternal (package:flutter_tools/src/build_system/build_system.dart:526:25) #2 _BuildInstance.invokeTarget. (package:flutter_tools/src/build_system/build_system.dart:481:35) #3 new Future.sync (dart:async/future.dart:224:31) #4 AsyncMemoizer.runOnce (package:async/src/async_memoizer.dart:43:45) #5 _BuildInstance.invokeTarget (package:flutter_tools/src/build_system/build_system.dart:481:21) #6 BuildSystem.build (package:flutter_tools/src/build_system/build_system.dart:419:36) #7 _AsyncAwaitCompleter.start (dart:async-patch/async_patch.dart:43:6) #8 BuildSystem.build (package:flutter_tools/src/build_system/build_system.dart:400:28) #9 buildWeb (package:flutter_tools/src/web/compile.dart:33:48) #10 _asyncThenWrapperHelper. (dart:async-patch/async_patch.dart:71:64) #11 _rootRunUnary (dart:async/zone.dart:1132:38) #12 _CustomZone.runUnary (dart:async/zone.dart:1029:19) #13 _FutureListener.handleValue (dart:async/future_impl.dart:137:18) #14 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:678:45) #15 Future._propagateToListeners (dart:async/future_impl.dart:707:32) #16 Future._completeWithValue (dart:async/future_impl.dart:522:5) #17 _AsyncAwaitCompleter.complete (dart:async-patch/async_patch.dart:30:15) #18 _completeOnAsyncReturn (dart:async-patch/async_patch.dart:288:13) #19 injectPlugins (package:flutter_tools/src/plugins.dart) #20 _asyncThenWrapperHelper. (dart:async-patch/async_patch.dart:71:64) #21 _rootRunUnary (dart:async/zone.dart:1132:38) #22 _CustomZone.runUnary (dart:async/zone.dart:1029:19) #23 _FutureListener.handleValue (dart:async/future_impl.dart:137:18) #24 Future._propagateToListeners.handleValueCallback (dart:async/future_impl.dart:678:45) #25 Future._propagateToListeners (dart:async/future_impl.dart:707:32) #26 Future._completeWithValue (dart:async/future_impl.dart:522:5) #27 Future._asyncComplete. (dart:async/future_impl.dart:552:7) #28 _rootRun (dart:async/zone.dart:1124:13) #29 _CustomZone.run (dart:async/zone.dart:1021:19) #30 _CustomZone.runGuarded (dart:async/zone.dart:923:7) #31 _CustomZone.bindCallbackGuarded. (dart:async/zone.dart:963:23) #32 _microtaskLoop (dart:async/schedule_microtask.dart:41:21) #33 _startMicrotaskLoop (dart:async/schedule_microtask.dart:50:5) #34 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:116:13) #35 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:173:5) Exception: lib/main.dart:44:38: Error: A value of type 'HttpClient' can't be assigned to a variable of type 'IClient'. - 'HttpClient' is from 'package:pressy_admin/utils/network/http_client.dart' ('lib/utils/network/http_client.dart'). - 'IClient' is from 'lib/utils/network/base_client.dart'. services.addScoped((_) => HttpClient()); ^ lib/main.dart:50:24: Error: The argument type 'IClient/*1*/' can't be assigned to the parameter type 'IClient/*2*/'. - 'IClient/*1*/' is from 'lib/utils/network/base_client.dart'. - 'IClient/*2*/' is from 'package:pressy_admin/utils/network/base_client.dart' ('lib/utils/network/base_client.dart'). client: services.getService(), ^ lib/main.dart:55:24: Error: The argument type 'IClient/*1*/' can't be assigned to the parameter type 'IClient/*2*/'. - 'IClient/*1*/' is from 'lib/utils/network/base_client.dart'. - 'IClient/*2*/' is from 'package:pressy_admin/utils/network/base_client.dart' ('lib/utils/network/base_client.dart'). client: services.getService(), ^ lib/main.dart:60:24: Error: The argument type 'IClient/*1*/' can't be assigned to the parameter type 'IClient/*2*/'. - 'IClient/*1*/' is from 'lib/utils/network/base_client.dart'. - 'IClient/*2*/' is from 'package:pressy_admin/utils/network/base_client.dart' ('lib/utils/network/base_client.dart'). client: services.getService(), ^ lib/main.dart:66:24: Error: The argument type 'IClient/*1*/' can't be assigned to the parameter type 'IClient/*2*/'. - 'IClient/*1*/' is from 'lib/utils/network/base_client.dart'. - 'IClient/*2*/' is from 'package:pressy_admin/utils/network/base_client.dart' ('lib/utils/network/base_client.dart'). client: services.getService())); ^ lib/main.dart:71:24: Error: The argument type 'IClient/*1*/' can't be assigned to the parameter type 'IClient/*2*/'. - 'IClient/*1*/' is from 'lib/utils/network/base_client.dart'. - 'IClient/*2*/' is from 'package:pressy_admin/utils/network/base_client.dart' ('lib/utils/network/base_client.dart'). client: services.getService())); ^ Error: Compilation failed. Failed to compile application for the Web flutter doctor summary: [✓] Flutter (Channel master, v1.10.15-pre.121, on Mac OS X 10.15 19A583, locale en-US) • Flutter version 1.10.15-pre.121 at /Users/drlegend/Documents/installation_files/flutter • Framework revision b857632306 (4 hours ago), 2019-10-15 00:07:32 -0700 • Engine revision 540fc977bb • Dart version 2.6.0 (build 2.6.0-dev.7.0 70a7ef3f58) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.2) • Android SDK at /Users/drlegend/Library/Android/sdk • Android NDK location not configured (optional; useful for native profiling support) • Platform android-29, build-tools 29.0.2 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS (Xcode 11.0) • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 11.0, Build version 11A420a • CocoaPods version 1.8.3 [✓] Chrome - develop for the web • Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome [✓] Android Studio (version 3.5) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin version 40.2.2 • Dart plugin version 191.8423 • Java version OpenJDK Runtime Environment (build 1.8.0_202-release-1483-b49-5587405) [✓] VS Code (version 1.39.0) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.4.1 [✓] Connected device (2 available) • Chrome • chrome • web-javascript • Google Chrome 77.0.3865.90 • Headless Server • headless-server • web-javascript • Flutter Tools • No issues found! issues in main.dart file void main() { BlocSupervisor.delegate = SimpleBlocDelegate(); runApp(Application(services: configureServices())); } IServiceCollection configureServices() { final services = ServiceCollectionImpl(); services.addSingleton((_) => AuthSessionImpl()); services.addSingleton((_) => MemberSessionImpl()); services.addScoped((_) => HttpClient()); // on this line services.addScoped((_) => ApiEndpointProvider()); services.addScoped((services) => AuthDataSourceImpl( apiEndpointProvider: services.getService(), client: services.getService(), authSession: services.getService())); services.addScoped((services) => OrderDataSourceImpl( apiEndpointProvider: services.getService(), client: services.getService(), authSession: services.getService())); services.addScoped((services) => ArticleDataSourceImpl( apiEndpointProvider: services.getService(), client: services.getService(), authSession: services.getService())); services.addScoped((services) => SlotDataSourceImpl( apiEndpointProvider: services.getService(), authSession: services.getService(), client: services.getService())); services.addScoped((services) => MemberDataSourceImpl( apiEndpointProvider: services.getService(), authSession: services.getService(), client: services.getService())); return services; } //this is my serviceCollectionimpl class import 'package:flutter_simple_dependency_injection/injector.dart'; class ServiceCollectionImpl implements IServiceCollection { static const String _INJECTOR_NAME = "@pressy/injector"; Injector _injector = Injector.getInjector(_INJECTOR_NAME); @override void addSingleton(ServiceFactory factory, {String key}) => _injector.map((_) => factory(this), isSingleton: true, key: key); @override void addScoped(ServiceFactory factory, {String key}) => _injector.map((_) => factory(this), key: key); @override void addInstance(IService instance, {String key}) { _injector.map((_) => instance, isSingleton: true, key: key); } @override IService getService({String key}) => _injector.get(key: key); }
jonsamwell commented 4 years ago

It looks like you have two versions of IClient

'IClient/1/' is from 'lib/utils/network/base_client.dart'.
'IClient/2/' is from 'package:pressy_admin/utils/network/base_client.dart'
('lib/utils/network/base_client.dart').
client: services.getService(),
^
lib/main.dart:66:24:
Error: The argument type 'IClient/1/' can't be assigned to the parameter type 'IClient/2/'.

While they might look the same the compiler thinks they are different.

Perhaps you are referring to IClient using a relative url somewhere 'lib/utils/network/base_client.dart' but a package url somewhere else 'package:pressy_admin/utils/network/base_client.dart'

jonsamwell commented 4 years ago

Also are you missing a Type parameter from all your services.getService() calls. Should it be for example

@override
IService getService<TType>({String key}) =>
_injector.get<TType>(key: key);
}

The injector won't know what type of service you want it go get.

So instead of this (which you are currently doing)

services.addScoped((services) => AuthDataSourceImpl(
apiEndpointProvider: services.getService(),
client: services.getService(),
authSession: services.getService()));

You would do this

services.addScoped((services) => AuthDataSourceImpl(
apiEndpointProvider: services.getService<ApiEndpointProvider>(),
client: services.getService<HttpClient>(),
authSession: services.getService<AuthSessionImpl>()));

Without providing the base type for instance a AuthSession to register a AuthSessionImpl against you are losing the typing ability to separate base types from super type (if that is your desired route which I think it might be looking at your naming convention.

jonsamwell commented 4 years ago

Closing due to lack of response