@ComponentDependency
The @ComponentDependency
annotation can be used to declare relationships
between Arez components. A component can declare that if a particular dependency is disposed then either the the component
should be disposed (if the @ComponentDependency.action
parameter is CASCADE
) or the reference to the disposed
component should be changed to null (if the @ComponentDependency.action
parameter is SET_NULL
). This feature is particularly
useful if an Arez component is derived from one or more other Arez components such as when a view model in a web
application is derived from entities that are propagated from a server.
The @ComponentDependency
annotation can be placed on an @Observable
property or on a non-observable property. The component will correctly monitor mutations of
@Observable
property to ensure that the correct dependency is monitored. For non-observable
properties, Arez assumes that the value returned from the method will never change and will cache the result
of invoking that method until the component is disposed.
It should be noted that only observable properties can be marked as a SET_NULL
dependency as that is the
only mechanism that Arez can use to trigger a re-evaluation of the condition function after a reference to
a dependency has been set to null.
An example:
@ArezComponent
public abstract class PersonViewModel
{
// This reference is immutable and the network replication
// layer is responsible for managing the lifecycle of person
// component and may dispose it when the Person entity is deleted
// on the server which should trigger this view model being disposed.
@ComponentDependency
@Nonnull
final Person _person;
...
// Let imagine there is a lot more logic and state on the view model
// to justify it's existence rather than just having view layer directly
// accessing underlying entities
@Nonnull
public Person getPerson()
{
return _person;
}
/**
* The Job entity is likewise controlled by the server
* and can be updated, removed on the server and replicated to the web
* browser. In this scenario the current job is just removed from the
* person view model.
*/
@ComponentDependency( action = ComponentDependency.Action.SET_NULL )
@Observable
@Nullable
public abstract Job getCurrentJob();
...
}