Logo

Factories

Factories (sometimes called factory capsules) are not unique to ReArch at all; in fact, ReArch just borrows the concept from OOP! From Wikipedia:

In object-oriented programming, a factory is an object for creating other objects; formally, it is a function or method that returns objects of a varying prototype or class

In ReArch, factories are just capsules that create objects on the fly and can consume some additional non-capsule parameters. Although factories may seem complex at first, they actually just boil down to some very straight forward syntactic sugar.

If you are coming from Riverpod, factories solve problems similar to those covered by Family & AutoDispose providers.

An Example#

Example Factory Capsule

Just like in capsules, factories are recreated whenever their dependency capsule(s) change, and anything consuming the factory will be given a new instance of the factory! In most situations, you will want to create a new instance of any factory-created objects whenever the factory instance itself changes.

Caching Created Objects#

Currently, this section only provides examples using the Dart implementation, since caching factory-created objects is often not needed and is not as trivial in Rust. (Although if you do need to, take a look at the run_on_change side effect.)

If you need to:

  • Cache a factory-created object (perhaps until the factory instance changes)
  • Dispose old factory-created objects to prevent leaks (perhaps when a new object is created)

Then take a look at the following snippet.

If you are familiar with React or flutter_hooks, this will feel exceedingly natural to you. See the dedicated documentation page on side effects for more.

Caching objects created with factories
MyCustomObject defaultParamMyCustomObjCapsule(CapsuleHandle use) {
  // Our factory capsule:
  final objFactory = use(objFactoryCapsule);

  // Some arbitrary capsule that may cause a rebuild
  // even when objFactory itself doesn't change:
  final someString = use(someCapsule);

  // Only recreate myObj when objFactory or someString change
  final myObj = use.memo(() {
    return objFactory(someString);
  }, [objFactory, someString]);

  // Whenever myObj changes, register the new object for disposal
  use.effect(() => myObj.dispose, [myObj]);

  return myObj;
}

This combination of memo and effect is very common, especially when handling FooBarControllers, so it is best to learn how to use them early on.