Skip to content

[feature request] registerCachedInstance? #367

Closed
@y-nk

Description

@y-nk

I would like to have the lazy singleton instance to be retained as long as its used, but destroyed when it's no longer in use. I know it sounds like a factory, but hear me out.

The project I work on currently is implementing the Clean Architecture, where repositories are registered as factories and requested the use-case classes. We write something such as:

class Repo {
  String getFoo() => "foo";
}

GetIt.instance.registerFactory(() => Repo());

class UseCase1 {
  String call() => GetIt.instance.get<Repo>().getFoo();
}

class UseCase2 {
  String call() => GetIt.instance.get<Repo>().getFoo();
}

class UseCase3 {
  String call() => GetIt.instance.get<Repo>().getFoo();
}

GetIt.instance.registerFactory(() => UseCase1());
GetIt.instance.registerFactory(() => UseCase2());
GetIt.instance.registerFactory(() => UseCase3());

class MyBloc {
  UseCase1 usecase1 = GetIt.instance()
  UseCase2 usecase2 = GetIt.instance()
  UseCase3 usecase3 = GetIt.instance()
}

When doing ↑, repositories get instantiated quite too often (everytime UsecaseX.call get called) so it's not ideal.

class Repo {
  String getFoo() => "foo";
}

GetIt.instance.registerFactory(() => Repo());

class UseCase1 {
  Repo repo = GetIt.instance()
  String call() => this.repo.getFoo();
}

class UseCase2 {
  Repo repo = GetIt.instance()
  String call() => this.repo.getFoo();
}

class UseCase3 {
  Repo repo = GetIt.instance()
  String call() => this.repo.getFoo();
}

GetIt.instance.registerFactory(() => UseCase1());
GetIt.instance.registerFactory(() => UseCase2());
GetIt.instance.registerFactory(() => UseCase3());

class MyBloc {
  UseCase1 usecase1 = GetIt.instance()
  UseCase2 usecase2 = GetIt.instance()
  UseCase3 usecase3 = GetIt.instance()
}

We can try to make it better. When doing ↑, repositories get created less often but still there's one instance per Usecase instances, so still not ideal.

class Repo {
  String getFoo() => "foo";
}

GetIt.instance.registerLazySingleton(() => Repo());

class UseCase1 {
  String call() => GetIt.instance.get<Repo>().getFoo();
}

class UseCase2 {
  String call() => GetIt.instance.get<Repo>().getFoo();
}

class UseCase3 {
  String call() => GetIt.instance.get<Repo>().getFoo();
}

GetIt.instance.registerFactory(() => UseCase1());
GetIt.instance.registerFactory(() => UseCase2());
GetIt.instance.registerFactory(() => UseCase3());

class MyBloc {
  UseCase1 usecase1 = GetIt.instance()
  UseCase2 usecase2 = GetIt.instance()
  UseCase3 usecase3 = GetIt.instance()
}

When doing ↑, repo instance remains in memory forever, so it's currently the best but it clutters the memory forever, so it's even better... but still not there 100%.

What I would like to have is a Cached Instance which could be very similar to registerLazySingleton but the reference to the instance would be retained in a WeakReference in GetIt, so that it is a singleton as long as it is used somewhere, but as soon as every user-land reference is gone, it would turn to null and be garbage collected.


We currently are experimenting wrapping our UseCase class with a Finalizer, so that we can call manually resetLazySingleton() which would have the same effect. What i'm proposing/requesting is that it became a feature of the library 🙏

Thank you for your time reading this

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions