Messaging
The handler must use the recipient argument so a weak subscribe does not pin the ViewModel. Do not write (msg) => this.Refresh() — that captures this and defeats the weak table.
hub.Subscribe<HomeViewModel, CartChanged>(
this,
static (vm, _) => vm.Refresh(),
weak: true);