Skip to content
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

Export de binds na v6 do flutter_modular #916

Open
darcanj0 opened this issue Nov 18, 2023 · 7 comments
Open

Export de binds na v6 do flutter_modular #916

darcanj0 opened this issue Nov 18, 2023 · 7 comments
Labels
new New issue request attention question Questions about using some feature or general working of the package

Comments

@darcanj0
Copy link

Ambiente

  flutter_modular: ^6.3.2
  mobx: ^2.2.1
  flutter_mobx: ^2.1.1

Descrição
Estou com dificuldades para conseguir compartilhar uma classe de Store feita com Mobx entre dois módulos da minha aplicação.

Tenho um Store de Autenticação (AuthStore) definido no meu AuthModule. Ele tem essa estrutura de dependências:

AuthStore -> AuthService -> ApiService

Ou seja, ele depende de um AuthService, que por sua vez, depende de um ApiService

No meu AuthModule, todas essas três classes já estão listadas dentro dos binds como Singletons, de tal forma que consigo usar meu AuthStore normalmente dentro do AuthModule.

class AuthModule extends Module {
  @override
  void binds(Injector i) {
    i.addSingleton<IApiService>(() => IApiService());
    i.addSingleton<IAuthService>(() => IAuthService());
    i.addSingleton(() => AuthStore.instance);
  }

  @override
  void exportedBinds(Injector i) {
    i.get<IApiService>();
    i.get<IAuthService>();
    i.get<AuthStore>();
  }
}

Tenho a necessidade de usar esse store dentro de um HomeModule.
Tanto AuthModule, quanto HomeModule já estão registrados como módulos no AppModule.
Também, já importei o AuthModule para dentro do meu HomeModule.

O problema está sendo em descobrir qual método do injetor eu uso, para registrar esse store, para ser exportado dentro do AuthModule.
Quando uso qualquer um dos métodos i.add.. do injetor, recebo um erro apontando que a classe já existe no injetor.
Por outro lado, quando uso algum método i.get , ele diz que a instância que é pedida no get não está registrada.

Qual a maneira correta de realizar esse export?

Além disso, há outro problema:
Tem um momento da minha aplicação, em que eu saio do AuthModule, para navegar para o HomeModule. Nesse processo, o AuthModule está sendo encerrado, fazendo com que eu perca dados desse AuthStore, que eu gostaria de compartilhar. Minha ideia inicial era de ter dentro desse store um stream, para que eu pudesse controlar o estado de autenticação de um usuário no meu app.

Essa é uma decisão correta? Uma vez que eu conseguir exportar meu store, para ser usado em outro módulo, como posso prevenir que meu AuthModule (e consequentemente meu store) não seja encerrado?

Comportamento esperado
Necessitava que um store fosse compartilhado entre dois módulos, bem como suas dependências

Código

Exemplo de um Singleton

abstract class IAuthService {
  Future<void> login(LoginDto dto);
  Future<void> signup();
  Future<void> signupWithGoogle();
  Future<void> signupWithLinkedin();
  Future<void> signout();
  Stream<CurrentUser?> get userChanges;

  factory IAuthService() => AuthMockService.instance;
}

O AuthStore mencionado

class AuthStore extends _AuthStore with _$AuthStore {
  AuthStore._({required super.authService});

  static AuthStore get instance =>
      AuthStore._(authService: Modular.get<IAuthService>());
}

abstract class _AuthStore with Store {
  final IAuthService service;

  @observable
  ObservableStream<CurrentUser?> userChanges;

  @action
  Future<void> signup() async {
    await service.signup();
  }

  _AuthStore({required IAuthService authService})
      : service = authService,
        userChanges = ObservableStream<CurrentUser?>(
          authService.userChanges,
          initialValue: null,
        );
}
@darcanj0 darcanj0 added new New issue request attention question Questions about using some feature or general working of the package labels Nov 18, 2023
@eduardoflorence
Copy link

Olá @darcanj0,
O comentário abaixo vai ajudar você:
#914 (comment)

@railsonsm
Copy link

Eu estou um pouco confuso nessa atualização. Pq n deixar a gente criar binds no module principal que possa ser usado em todo o app? @jacobaraujo7

@danilocarreiro
Copy link

Estou passando pelo mesmo problema

@eduardoflorence
Copy link

@railsonsm e @danilocarreiro, se o bind foi criado no módulo principal, você pode usar em todo o App, basta usar Modular.get<SeuBind>().

O que não pode ser feito é você recuperar automaticamente na área de binds de outro módulo para injetar como dependência em outro Bind, pois nesse caso precisa exportar num módulo "Core" e importar nos módulos que precisa.

@railsonsm
Copy link

railsonsm commented Mar 19, 2024

Opa @eduardoflorence era justamente isso q eu estava tentando fazer.

Eu tenho esses binds do meu AppModule

image

Ai eu estava tentando usar eles ali no meu UsuarioService que só funcionou injetando o AppModule no meu outro modulo.

image

Acredito q nesse caso seria interessante criar apenas um modulo com Binds que eu queira usar em outros lugares, correto? Como fazemos no angular

@eduardoflorence
Copy link

Exatamente @railsonsm
Eu costumo fazer um CoreModule com os binds que desejo compartilhar e injeto no AppModule e nos outros módulos que preciso desses binds.
Nesse CoreModule você utiliza o exportedBinds assim, por exemplo:

class CoreModule extends Module {
  @override
  void exportedBinds(i) {
    i.addSingleton<UserDataSource>(UsesDataSourceImpl.new);
    i.addSingleton<UserRepository>(UserRepositoryImpl.new);
  }
}

@railsonsm
Copy link

Show @eduardoflorence, muito bom! Tmj!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new New issue request attention question Questions about using some feature or general working of the package
Projects
None yet
Development

No branches or pull requests

4 participants