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

Migração de Modular v5 para v6 #957

Open
adrinebt opened this issue Apr 22, 2024 · 14 comments
Open

Migração de Modular v5 para v6 #957

adrinebt opened this issue Apr 22, 2024 · 14 comments
Labels
new New issue request attention question Questions about using some feature or general working of the package

Comments

@adrinebt
Copy link

adrinebt commented Apr 22, 2024

Tenho o seguinte código, como poderia migrar para a v6?

Tenho LoginModule que está dentro de app/modules/login

class LoginModule extends Module {
  @override
  final List<Bind> binds = [
    Bind.lazySingleton((i) => LoginController(
        i<IUsuarioService>(),
        i<IConfiguracaoAppService>(),
        i.get<LoginRepository>(),
        i.get<UsuarioModel>(),
    ),
    ),
    Bind.lazySingleton((i) => LoginRepository()),
    Bind.lazySingleton((i) => UsuarioModel())
  ];

  @override
  final List<ModularRoute> routes = [
    ChildRoute(Modular.initialRoute, child: (_, args) => const LoginPage()),
  ];
}

Tenho AppModule que contém todos os módulos

@override
  final List<ModularRoute> routes = [
    ModuleRoute(Modular.initialRoute, module: SplashModule()),
    ModuleRoute('/login', module: LoginModule()),
];
@adrinebt adrinebt added new New issue request attention question Questions about using some feature or general working of the package labels Apr 22, 2024
@eduardoflorence
Copy link

Olá @adrinebt,

Veja essa parte da documentação com a comparação: https://modular.flutterando.com.br/docs/flutter_modular/migration-5-to-6

@adrinebt
Copy link
Author

adrinebt commented Apr 23, 2024

Minha dúvida é sobre como lidar com o caso do construtor de LoginController que tem as dependências IUsuarioService, IConfiguracaoAppService como funcionaria na migração não encontrei nada parecido na documentação

@override
  final List<Bind> binds = [
    Bind.lazySingleton((i) => LoginController(
        i.get<IUsuarioService>(),
        i.get<IConfiguracaoAppService>(),
        i.get<LoginRepository>(),
        i.get<UsuarioModel>(),
    ),
    ),
    Bind.lazySingleton((i) => LoginRepository()),
    Bind.lazySingleton((i) => UsuarioModel())
  ];

@eduardoflorence
Copy link

IUsuarioService e IConfiguracaoAppService estão no binds de outro Módulo? Se sim, pode mostrar o nome desse outro módulo e a parte do binds dele para eu te dar um exemplo correto?

@adrinebt
Copy link
Author

Outro exemplo é no módulo do Splash que vem antes do login que mostrei anteriormente

class SplashModule extends Module {
  @override
  final List<Bind> binds = [
    Bind.lazySingleton((i) => SplashController()),
    Bind.lazySingleton((i) => LoginController(
        i.get<IUsuarioService>(),
        i.get<IConfiguracaoAppService>(),
        i.get<LoginRepository>(),
        i.get<UsuarioModel>(),
  ),
    ),
  ];

  @override
  final List<ModularRoute> routes = [
    ChildRoute(Modular.initialRoute, child: (_, args) => const SplashPage()),
  ];
}

@eduardoflorence
Copy link

Para te dar o exemplo na versão 6 corretamente, eu precisaria saber onde são declaradas as dependências IUsuarioService e IConfiguracaoAppService. Elas estão no binds seu AppModule ou num SharedModule? Ou elas estão no binds do LoginModule e SplashModule, só que você cortou ao colocar o código nos exemplos acima?

Ou seja, no LoginModule e SplashModule, que mostrou acima, você obtém essas dependências (IUsuarioService e IConfiguracaoAppService), mas em algum módulo anterior você colocou essas dependências no binds para serem usadas posteriormente.

@adrinebt
Copy link
Author

IUsuarioService e IConfiguracaoAppService são dependências de LoginController e declaradas em LoginModule.
este por sua vez é declarado no AppModule como no código abaixo

@override
  final List<ModularRoute> routes = [
    ModuleRoute(Modular.initialRoute, module: SplashModule()),
    ModuleRoute(routeLogin, module: LoginModule()),
    ModuleRoute(routeHome, module: HomeModule()),
    ModuleRoute(routeConsulta, module: ConsultaModule()),
  ];

@eduardoflorence
Copy link

Ok, acredito que não tenha você não compreendeu a informação que preciso, mas vou te dar um exemplo de como eu faria na versão 6 do Modular:

  • Como IUsuarioService e IConfiguracaoAppService serão usados em mais de um módulo, o ideal é colocá-los num módulo à parte com exportação. Vou supor que IUsuarioService e IConfiguracaoAppService são interfaces e UsuarioServiceImpl e ConfiguracaoAppServiceImpl são as implementações destas interfaces. Faça um CoreModule desta forma:
class CoreModule extends Module {
  @override
  void exportedBinds(Injector i) {
    i.addSingleton<IUsuarioService>(UsuarioServiceImpl.new);
    i.addSingleton<IConfiguracaoAppService>(ConfiguracaoAppServiceImpl.new);
  }
}
  • Seu LoginModule, importará CoreModule e ficará então desta forma:
class LoginModule extends Module {
  @override
  List<Module> get imports => [CoreModule()];

  @override
  void binds(Injector i) {
    i.addLazySingleton(LoginController.new),
    i.addLazySingleton(LoginRepository.new),
    i.addLazySingleton(UsuarioModel.new)
  } 

  @override
  void routes(RouteManager r) {
    r.child(Modular.initialRoute, child: (context) => const LoginPage()),
  }
}

Ao fazer LoginController.new o sistema de injeção de dependências fará a injeção automática de cada dependência que LoginController precisa via construtor, basta que exista um bind dessas dependências, que foi o que fiz nos exemplos acima.

@adrinebt
Copy link
Author

Perdão, não sei se essa era a sua dúvida agora creio que compreendi. IUSuarioService e IConfiguracaoAppService são de fato interfaces implementadas respectivamente em UsuarioService e ConfiguracaoAppService que como no código abaixo estão declaradas nos binds do AppModule

@override
  final List<Bind> binds = [
    Bind.lazySingleton((i) => ConfiguracaoAppService()),
    Bind.lazySingleton((i) => UsuarioService(i<IUsuarioRepository>())),
    Bind.lazySingleton((i) => CustomDio(i<BaseOptions>())),
    Bind(
      (i) => BaseOptions(
        baseUrl: baseUrlNova,
        contentType: Headers.formUrlEncodedContentType,
        connectTimeout: const Duration(seconds: 90),
        receiveTimeout: const Duration(seconds: 90),
        sendTimeout: const Duration(seconds: 90),
        receiveDataWhenStatusError: true,
      ),
    ),
  ];

@eduardoflorence
Copy link

Isso mesmo que eu estava querendo saber.
Esse Bind que mostrou agora por último ficará assim:

class CoreModule extends Module {
  @override
  void exportedBinds(Injector i) {
    i.addLazySingleton<IConfiguracaoAppService>(ConfiguracaoAppService.new);
    i.addLazySingleton<IUsuarioService>(UsuarioService.new);
    i.addLazySingleton<CustomDio>(CustomDio.new), 
    i.addInstance<BaseOptions>(
      () => BaseOptions(
        baseUrl: baseUrlNova,
        contentType: Headers.formUrlEncodedContentType,
        connectTimeout: const Duration(seconds: 90),
        receiveTimeout: const Duration(seconds: 90),
        sendTimeout: const Duration(seconds: 90),
        receiveDataWhenStatusError: true,
      ),
    ),
  }
}

Em cada módulo que precisar do IConfiguracaoAppService e IUsuarioService, você precisará importar este CoreModule como mostrei no exemplo anterior em LoginModule. Essa é a orientação no Modular 6 (No 5 não precisava)

@eduardoflorence
Copy link

Obs.: Não use o AppModule para fazer esse exportedBinds das dependências que serão compartilhadas, use um módulo em separado (orientação para modular 6) como o CoreModule do meu exemplo. Se até o AppModule precisar das dependências, pode importar também.

@rodrigolmacedo
Copy link

Interessante, não fiz a migração por conta disso, não havia entendido.

@adrinebt
Copy link
Author

nesse caso o AppModule serviria somente para declarar os modules como SplashModule, LoginModule?

@eduardoflorence
Copy link

nesse caso o AppModule serviria somente para declarar os modules como SplashModule, LoginModule?

Sim, você até pode colocar bind nele, mas seria só de dependências que seriam usadas exclusivamente no AppModule, caso ele tivesse uma página inicial, antes de ir para outro módulo, por exemplo.
Obs.: Você consegue acessar um bind do AppModule em qualquer outro módulo declarado por ele, fazendo Modular.get<SuaDependencia>(), mas isso não é aconselhável, pois "estraga" a sua arquitetura, já que seria por fora da injeção de dependências.

@ricardomac
Copy link

@eduardoflorence deveria colocar esse exemplo/explicação sua na doc, atualizar a mesma.
Estava com o mesmo cenário com o da moça acima, passei 1 dia inteiro tentando, ate chegar na sua explicação.

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