Skip to content

Unable to get or isRegistered without passing type. #197

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
CobeGreene opened this issue Jun 4, 2021 · 10 comments
Closed

Unable to get or isRegistered without passing type. #197

CobeGreene opened this issue Jun 4, 2021 · 10 comments

Comments

@CobeGreene
Copy link

CobeGreene commented Jun 4, 2021

image

Hello,

I'm getting an error (on 7.1.3) when I attempt to call get or isRegistered without the template type pass in, I would really like this functionality so I only have to pass the instance name and can make calls to get without knowing the type at compile type, it work in a previous build 4.0.4. Anyways, I've reverted back to 4.0.4 for now, but it's a really good package and I would really like to stay up to date.

image

I've narrow it down to this assert statement.

image

@escamoteur
Copy link
Collaborator

what is the return type of the function where you do that return?

@CobeGreene
Copy link
Author

CobeGreene commented Jun 4, 2021

The return type is a service with a dynamic template, the dynamic template is because I've multiple services that implement and extend this base class with their own concrete type. I've a router that automatically sets up a Change Notifier Provider for pages (using the provider package), however, the router must route for all pages where the types it needs to fetch change per a page so I was using the instance name to get the right service.

ModelService<dynamic> // The return type

@CobeGreene
Copy link
Author

Thank you for the time you have already spent reading my question, it's much appreciate. I hope you don't mind reading some more, here's some code on what I'm essentially trying to do:

import 'package:get_it/get_it.dart';

abstract class ModelService<T> {
  T get(int id); // Common method for models for router to get Models from
}
class ObjectA { final int id; ObjectA(this.id); }
abstract class ObjectAService<ObjectA> extends ModelService {
  // methods for ObjectAService ...
}
class AppObjectAService implements ObjectAService {
  ObjectA get(int id) => ObjectA(id); // implements ModelService 
  // implements ObjectAService ... 
}
class ObjectB { final int id; ObjectB(this.id); }
abstract class ObjectBService<ObjectB> extends ModelService {
  // methods for ObjectAService ...
}
class AppObjectBService implements ObjectBService {
  ObjectB get(int id) => ObjectB(id); // implements ModelService 
  // implements ObjectBService ... 
}

GetIt instance = GetIt.instance;

Type typeOf<T>() => T;
String nameOf<T>() => typeOf<T>().toString();

void main() {
  instance.registerLazySingleton<ObjectAService>(() => AppObjectAService(), instanceName: nameOf<ObjectA>());
  instance.registerLazySingleton<ObjectBService>(() => AppObjectBService(), instanceName: nameOf<ObjectB>());
  // Each page take a set of arguments
  var arguments = [ObjectA, ObjectB];
  var service =  instance.get(instanceName: arguments[0].toString()); // This throws Error 1. 
  var service2 =  instance.get<ModelService<dynamic>>(instanceName: arguments[0].toString()); // This throws Error 2. 
  // With the service, I use their get method to get the desired model for my page. 
  // Very handy because in my actual code,  model service get method returns a Future,
  // for it might need to talk to an API, and I have loading screen that now my pages don't have to implement.
 // as well as the overhead of setting up a multichangeprovider when I'm using the provider class. 
}

Here's Error 1:
image

Here's Error 2:
image

@CobeGreene
Copy link
Author

Hi, not sure how much I like this solution. But if I registered it as a ModelService and get as ModelService, I can then cast to the extended class.

instance.registerLazySingleton<ModelService>(() => AppObjectAService(),
      instanceName: nameOf<ObjectA>());
var arguments = [ObjectA, ObjectB];
var service =  instance.get<ModelService>(instanceName: arguments[0].toString()) as ObjectAService;

@escamoteur
Copy link
Collaborator

Why would you use the type as an instanceName? I tried to uderstand what you are doing there and I failed.
Could you explain in simple words what you try to achieve? I have the feeling you are doing it way to compllicated

@CobeGreene
Copy link
Author

Hi, yes some of the code is complicated, but the rest of the UI benefits. I'm using the model type as instanceName because each route has a list of arguments and I'm not able to write the following:

instance.get<arguments[index]>(); 

A route looks like the following:

static AppRoute route() => AppRoute(
      path: '/member/:id/group/:groupId',
      arguments: [Member, Group],
      build: () => MemberGroupPage());

and the MemberGroupPage gets the benefit that the member and group will both have their change notified setup for any changes, so I can write code like this without having to setup a multi-provider, plus there's some handling of loading that may occur if the model service has to fetch from the API.

this.context.watch<Group>().groupName;

@escamoteur
Copy link
Collaborator

But every page normally knows which objects it's needs, so why pass that in from the outside. Also I recommend using the get_it_mixin instead of provider when you already have objects inside get_it. you won't need any of that then.

@fullflash
Copy link

```dart
instance.get<arguments[index]>(); 

as author mentioned it is usefull to be aple to use type as argument.

without manually typeing class type it is impossible to check get_it isRegistered function.
and it is impossible to use type from variable like instance.get<arguments[index]>();

@escamoteur
Copy link
Collaborator

@fullflash you mean you want to check with a variable of type Type if that type is registered?

@fullflash
Copy link

@fullflash you mean you want to check with a variable of type Type if that type is registered?

yes exactly. to avoid non_type_as_type_argument compiler error.
in dart it is impossible to use Type as argument.
such functions would be helpful

isRegisteredWithName
unregisterWithName

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants