Export de binds na v6 do flutter_modular
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,
);
}
Olá @darcanj0, O comentário abaixo vai ajudar você: https://github.com/Flutterando/modular/issues/914#issuecomment-1807200231
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
Estou passando pelo mesmo problema
@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.
Opa @eduardoflorence era justamente isso q eu estava tentando fazer.
Eu tenho esses binds do meu AppModule
Ai eu estava tentando usar eles ali no meu UsuarioService que só funcionou injetando o AppModule no meu outro modulo.
Acredito q nesse caso seria interessante criar apenas um modulo com Binds que eu queira usar em outros lugares, correto? Como fazemos no angular
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);
}
}
Show @eduardoflorence, muito bom! Tmj!