Skip to content
Avalloy.UpdatesAvalloy.Updates

In-app updates ​

Avalloy.Updates is the runtime half of an app's update story: is there a newer release, download it, and either restart into it or stage it for the next quit, narrating through a notifier. Velopack does the packaging and the install hooks; this package holds the policy. Its own package so Core stays free of Velopack.

sh
dotnet add package Avalloy.Updates

Wiring ​

The install and update hooks are a separate, earlier concern: VelopackApp.Build().Run() must be the first line of Main. Then register the pieces:

csharp
services.AddSingleton(new AppUpdateOptions
{
    AppName = "MyApp",
    RepoUrl = "https://github.com/me/myapp",   // GitHub Releases
    Prerelease = false,
});
services.AddSingleton<IUpdateSource, VelopackUpdateSource>();
services.AddSingleton<IUpdateNotifier, ToastUpdateNotifier>();
services.AddSingleton<UpdateService>();

And call it: silently at startup, and loudly when the user asks.

csharp
await updates.CheckAndApplyAsync(userInitiated: false);   // quiet unless it is actually updating
await updates.CheckAndApplyAsync(userInitiated: true);    // always answers

IsSupported is false in dev runs and non-packaged builds, and the service no-ops there, so rig run and loose builds are unaffected.

The seams ​

IUpdateSource is where updates come from and how they get applied. It exists so the actual logic, the overlap guard, the silent-versus-asked-for split, stage-versus-restart, and failure reporting, is testable without a packaged build, a release feed or a process restart. VelopackUpdateSource is the real one, GitHub Releases via Velopack, and deliberately a thin adapter holding no policy.

IUpdateNotifier is how the service talks to the user, with three levels because updating has three things to say: something is happening, it worked, it did not. What gets said is the behaviour worth pinning: a silent startup check stays quiet unless it is actually updating, while a user who asked gets an answer either way. ToastUpdateNotifier is the production one.

AppUpdateOptions carries the app name, the repository URL, an optional access token for a private repository, whether to take prereleases, and an optional channel.

Released under the MIT License.