Get It, inyección de dependencias en Flutter

El otro día hablábamos de Koin, un inyector de dependencias para Kotlin, hoy volvemos a la carga con otro inyector de dependencias pero en esta ocasión para Flutter. Get It es la librería que nos suministra la solución para poder trabajar de una forma mucho más fácil y cómoda con todas las dependencias que nuestras clases requieran y además de forma muy fácil.

Get It tiene una gran similitud con Koin, salvando las distancias en cuanto al lenguaje, y es que al igual que Koin, Get It utiliza el patrón Service Locator para realizar su trabajo. Ya vimos cuales eran las diferencias más significativas el otro día.

Puede que muchos os preguntéis porque tanto bombo con los inyectores de dependencias, pero la verdad es que pueda que sea lo mas utilizado y lo más fundamental a la hora de crear un desarrollo. Una vez que un proyecto empieza a crecer, y las clases empiezan a depender unas de otras, es una locura el intentar controlar todo este árbol de dependencias sin un inyector. 

Además nos facilita mucho la labor a la hora de crear los test, ya que solo debemos de crear una nuevo árbol de dependencias con los mocks que necesitemos para que los test se puedan ejecutar.

Siempre y cuando no nos olvidemos de poner en práctica, el principio de Inversión de Dependencias. Siempre usaremos abstracciones por el constructor, y nunca implementaciones concretas. Haremos un post sobre este principio más adelante.

Get It, ejemplo práctico de inyección de dependencias en Flutter

Para el ejemplo, y para que se vea de forma sencilla como funciona Get It, he creado un proyecto donde tenemos tres clases:

  • MainController: Actuará como la vista de la app. Es donde están todos los widgets.
  • MainViewModel: será la clase que conectará con el repositorio, obtenga datos y se los dará a la vista para que los pinte. La vista solo se comunica con esta clase.
  • MainRepository: Es el repositorio de datos. 
  • Además tenemos el archivo Main que incializa la aplicación y el archivo Injector donde configuraremos todo el árbol de dependencias.

Dependencias entre clases

En la clase MainController tenemos que inyectar una instancia de la clase MainViewModel para que estas dos clases puedan comunicarse. 

La clase MainViewModel tiene que tener una relación con la clase MainRepository para poder pasarle datos. Esta relación implica que debe de existir una instancia de MainRepository en la clase MainViewModel y esta instanciación se hará en el constructor.

A su vez la clase MainRepository, es una concreción de la clase abstracta DataSource, justamente para poder desacoplar el origen de datos. Por tanto lo que pasaremos por el constructor de MainViewModel será la clase abstracta y no la implementación. Será el Inyector el que se encargue de decidir que implementación es la que corresponde.

Añadiendo Get It a nuestro proyecto.

Como toda dependencia en Flutter, esta se añade en el archivo pubspecs.yaml. En el momento de escribir este post, la versión de Get It era la:

get_it: ^4.0.2

Una vez tenemos la librería en nuestro proyecto vamos a ver como funciona. Lo primero que tenemos que hacer es configurar las dependencias que hemos dicho antes, para que una vez que nos hagan falta sea el inyector el que las resuelva y las inyecte.

Yo he creado el fichero Injector.dart y dentro he creado lo siguiente:


//creamos la instancia del inyector
//Este internamente la crea en forma de singleton
// si bien también es posible utilizarla así:
// GetIt.I.registerFactory( () => MainRepository());

GetIt locator = GetIt.instance;

//en este método es donde configuro todas las dependencias.
//Si son muchas podríamso tener más métodos, cada uno para cada capa o cada feature
//y que desde uno se ejejcuten todos.

void setupInjector() {
  //Aquí defino como debe de instanciarse la clase MainRepository
  //Indicamos que es del tipo DataSource y la instancia concreta
  locator.registerSingleton(MainRepository());
  //Defino la dependencia del ViewModel com una factoría.
  //Esto quiere decir que cada vez que se cree la vista mainController, e inyecte un MainViewModel
  // se creará una instancia distinta del MainViewModel
  //El MainViewModel tiene a su vez como dependencia al repositorio
  //nosotros solo debemos de indicar que es del tipo abstracto, el injector de encargará
  //de instanciar la clase concreta
  locator.registerFactoryParam(() =>
      MainViewModel(repository: locator.get());

}

En los comentarios está explicado cada línea de código. Creo que se entiende bien.

Para incializar el inyector lo que nos quedaría será llamar al método donde acabamos de definir todas las dependencias desde el inicio de la aplicación, en nuestro caso desde el archivo main:

void main() {
  setupInjector();
  runApp(MyApp());
}

Por último solo nos queda inyectar en el MainController la referencia la MainviewModel, esto lo haremos de esta forma:

class _MainControllerState extends State {

  final viewModel = locator.get();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text(widget.title),
      ),
      body: Center(
        child: Text('El mensaje es:  ${viewModel.fetchData()}'),
      ), // This trailing comma makes auto-formatting nicer for build methods.
    );
  }
}

Comentar que además de poder registrar las dependencias como Singleton o Factorias, Get It ofrece también la posibilidad de registraras como LazySingleton. En este caso la dependencia solo se creará cuando se llame por primera vez al objeto del que sea una dependencia esta clase.

getIt.registerLazySingleton(() =>MainRepository());

Básicamante esto es todo para iniciarse en la inyección de dependencias en Flutter con Get It.

Todo el código lo tenéis disponible en Github.

Comparte si lo consideras interesante
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.