본문 바로가기

Flutter

[Flutter] GetX를 사용해야할 이유3 - 종속성 관리(의존성 주입, 바인딩)

GetX의 의존성 주입

flutter에도 여러가지 의존성 주입 라이브러리가 있지만 GetX에서도 의존성 주입을 지원한다.


페이지를 실행할 때 의존성 주입 방법

GetX를 통해 페이지를 실행할 때 의존성을 주입하는 방법은 기본적으로 4가지를 지원한다.

해당 주입 방법들은 페이지가 종료될때 GetX에서 자동으로 인스턴스를 모두 메모리에서 날려준다.

[GETX] Instance "DependencyController" has been created

[GETX] "DependencyController" deleted from memory

위의 로그와 같이 생성될때와 삭제될 때 GetX에서 로그를 남겨 확인이 가능하다.


Get.put()

해당 페이지가 시작될때 인스턴스가 생성된다.

Get.to(const NextPage(), binding: BindingsBuilder(() {
  Get.put(DependencyController());
}));

Get.putAsync()

Get.to(const NextPage(), binding: BindingsBuilder(() {
  Get.putAsync<DependencyController>(() async {
    await Future.delayed(const Duration(seconds: 1));
    return DependencyController();
  });
}));

페이지 접근 후 비동기 작업이 필요할 경우 작업이 완료되고 인스턴스가 생성된다.

위의 코드의 경우 NextPage가 시작되고 1초 후 인스턴스가 생성된다.


Get.lazyPut()

Get.to(const NextPage(), binding: BindingsBuilder(() {
  Get.lazyPut<DependencyController>(() => DependencyController());
}));

해당 페이지에서 주입된 컨트롤러 인스턴스가 필요한 시점에 생성된다.

예를 들어

final controller = Get.find<DependencyController>();
controller.function();

위의 코드와 같이 NextPage()에서 해당 컨트롤러를 인스턴스화를 하는 시점에 생성된다.


Get.create()

Get.to(const NextPage(), binding: BindingsBuilder(() {
  Get.create<DependencyController>(() => DependencyController());
}));

해당 페이지에서 주입된 컨트롤러 인스턴스가 필요한 시점에 매번 새로 생성된다.

lazyPuy()과 비슷할 수 있지만 lazyPut()은 인스턴스를 싱글턴으로 생성 후 매번 재사용되지만, create()의 경우 매 시점마다 새로운 인스턴스를 생성하여 아마도 메모리적 효율이 떨어질것으로 보인다.


앱이 실행될 때 의존성 주입 방법

위의 방법들은 페이지에서 페이지로 전환될 때 의존성을 주입하는 방법이었다.

이번에는 앱이 실행될 때 미리 의존성 주입을 하고 방식을 정의하는 방법이다.

class Binding implements Bindings {
  @override
  void dependencies() {
    Get.put<MyGetXController>(MyGetXController(), permanent: true);
  }
}

기존의 Get.put() 방식을 주입을 정의하면, 위와 같이 Bindings 인터페이스를 구현하는 클래스를 dependencies를 상속받아 구현한다.

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      ...
      getPages: [
        ...
        GetPage(
          name: '/binding',
          page: () => const BindingPage(),
          binding: BindingPageBinding(),
        )
      ],
    );
  }
}

주입 정의가 되었으면 GetMaterialApp의 getPages에 만들었던 Binding을 다음과 같이 작성해준다.

Get.toNamed("/binding");

페이지 전환은 기존과 동일하다. 단, to(NextPage()) 와 같이 페이지를 직접 지정하면 주입이 되지않고 name을 사용해서 전환해야한다.

 

영속 상태의 의존성 주입

이전의 방법들을 사용하면 해당 페이지를 벗어날 경우 GetX에 의해 주입되었던 인스턴스들이 모두 삭제된다.

하지만 로그인 정보 같이 앱을 활동하면서 영속적으로 사용되어야하는 인스턴스를 생성하기 위해 두가지 방법이 있다.

Get.put<MyGetXController>(MyGetXController(), permanent: true);

기존의 주입 방식에서 permanent 값에 true를 주거나

class MyGetXService extends GetxService{
  .. controller 와 동일
}

GetXService를 상속받는 service를 생성하여 주입하는 방법이다.

이렇게 설정이 되면 기존의 방식과 동일하게 주입을 하는 시점(lazyPut은 인스턴스 사용 시)에 인스턴스가 생성되지만 페이지를 종료하더라도 인스턴스가 제거되지 않는다.

만약 사용되는 페이지 전환 시점과 무관하게 앱이 실행될 때 생성하고싶다면

void main() {
  Get.put<MyGetXController>(MyGetXController(), permanent: true);
  runApp(const MyApp());
}

다음과 같이 main에 선언해주면 된다.