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.
You should have a deployment strategy in place that takes a backup of the database before you deploy new versions
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.
You should have a deployment strategy in place that takes a backup of the database before you deploy new versions
Install-Package 'Llamachant.ExpressApp.UpdateScripts.Xpo'
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();
});
Install-Package 'Llamachant.ExpressApp.UpdateScripts.Xpo'
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();
});
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.
// 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;
}
}
}
public sealed class YourApplicationModule : ModuleBase, IUpdateScriptProvider
{
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, new UpdateScriptManager())
};
}
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);
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.
// 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;
}
}
}
public sealed class YourApplicationModule : ModuleBase, IUpdateScriptProvider
{
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, new UpdateScriptManager())
};
}
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);