Update Scripts
NuGet Package Details
Package Name
Llamachant.ExpressApp.UpdateScripts.Xpo
Overview
The Update Script Module provides a structured and maintainable way to manage one-time database update logic during deployment. Instead of placing all update code in Updater.cs, this module lets you define discrete, versioned update scripts that are executed only once per database, ensuring that critical changes are applied safely and automatically without manual intervention.
TIP:
You should have a deployment strategy in place that takes a backup of the database before you deploy new versions
Installation
Step 1: Install the Module
Install-Package 'Llamachant.ExpressApp.UpdateScripts.Xpo'
Step 2: Register the Module
public override void Setup(XafApplication application) {
base.Setup(application);
this.RequiredModuleTypes.Add(typeof(LlamachantFrameworkUpdateScriptsModuleXpo));
}
OR
services.AddXaf(Configuration, builder => {
builder.UseApplication<ExpressAppBlazorApplication>();
builder.Modules
.AddLlamachantFrameworkUpdateScriptsModuleXpo();
});
Setup
You define update scripts by implementing the IUpdateScript interface. Each script includes metadata (ID, description, creation date) and a Run method that performs the update using the provided IObjectSpace. The module executes scripts in order based on their CreatedDate, and only those that haven't run yet are applied.
You then register these scripts by implementing IUpdateScriptProvider in your ModuleBase class, allowing the module to automatically detect and run updates during application startup.
Notes:
- Scripts can be designated as Pre-Update or Post-Update, giving you control over when they are applied in the update process.
- You can disable update execution during debugging by setting
UpdateScriptManager.Instance.UpdateWhenDebugging = false.
Step 1: Create a new class that implements IUpdateScript
// You can create as many of these types of classes as you need
public class OneTimeUpdate : IUpdateScript
{
public string UpdateID { get; } = Guid.NewGuid().ToString(); //This must be unique
public string Description { get; } = "Perform a one time update";
public DateTime CreatedDate { get; } = DateTime.Parse("January 1, 2022");
public IUpdateScriptType ScriptType { get; } = IUpdateScriptType.PostUpdateScript;
public string Run(IObjectSpace space, Version databaseVersion)
{
try
{
//try to perform your update here using the IObjectSpace
return "Success";
}
catch (Exception ex)
{
return ex.Message;
}
}
}
Step 2: Implement the IUpdateScriptProvider interface on your ModuleBase
public sealed class YourApplicationModule : ModuleBase, IUpdateScriptProvider
{
public IList<IUpdateScript> GetPreUpdateScripts()
{
// This will automatically collect all IUpdateScripts in the current assembly
return UpdateScriptManager.GetInstance(this.ModuleManager.Modules)
.FindUpdateScriptsInAssembly(Assembly.GetExecutingAssembly(), IUpdateScriptType.PreUpdateScript);
}
public IList<IUpdateScript> GetPostUpdateScripts()
{
// This approach lets you determine which IUpdateScripts to release
//return new List<iupdatescript>() { new OneTimeUpdate() };
// This will automatically collect all IUpdateScripts in the current assembly
return UpdateScriptManager.GetInstance(this.ModuleManager.Modules)
.FindUpdateScriptsInAssembly(Assembly.GetExecutingAssembly(), IUpdateScriptType.PostUpdateScript);
}
}
Step 3: Initialize the UpdateScriptManager and add the updater
public override void Setup(XafApplication application)
{
base.Setup(application);
LlamachantFramework.UpdateScripts.Utils.UpdateScriptManager.GetInstance(application.Modules)?.Initialize(application); //The update script manager will find all IUpdateScriptProviders
}
public override IEnumerable<ModuleUpdater> GetModuleUpdaters(IObjectSpace objectSpace, Version versionFromDB)
{
ModuleUpdater updater = new DatabaseUpdate.Updater(objectSpace, versionFromDB);
return new[]
{
updater,
new LlamachantFramework.UpdateScripts.Xpo.DatabaseUpdate.Updater(objectSpace, versionFromDB, UpdateScriptManager.GetInstance(Application.Modules)))
};
}
Final Notes
- You define update scripts by implementing the
IUpdateScriptinterface. Each script includes metadata (ID, description, creation date) and a Run method that performs the update using the providedIObjectSpace. - The module executes scripts in order based on their CreatedDate, and only those that haven't run yet are applied.
- You can disable update execution during debugging by setting
UpdateScriptManager.Instance.UpdateWhenDebugging = false.