Integrate Application Builders into Existing Applications
- 8 minutes to read
In .NET 6+ applications, you can use fluent API-based application builders to configure your ASP.NET Core Blazor and WinForms applications (add extra Modules, enable the Security System, and so on). The Solution Wizard creates application builders automatically when you create an XAF solution in v22.1+.
This help topic describes how to integrate an application builder into your project created in v21.2 and earlier.
Step 1. Move Application Initialization Code
Implement the ILegacyInitializationXafApplication interface in your BlazorApplication / WinApplication descendants and comment out the
InitializeComponents
method in their constructors:Files: ASP.NET Core Blazor - MySolution.Blazor.Server\BlazorApplication.cs WinForms - MySolution.Win\WinApplication.cs
using DevExpress.ExpressApp.ApplicationBuilder; // ... public partial class MySolutionBlazorApplication : BlazorApplication, ILegacyInitializationXafApplication { public MySolutionBlazorApplication() { // InitializeComponent(); } void ILegacyInitializationXafApplication.InitializeComponent() => InitializeComponent(); // ... }
ILegacyInitializationXafApplication.InitializeComponent is called during application initialization.
In the
InitializeComponent
method, comment out the registration ofSystemModule
,SystemBlazorModule
, andSystemWindowsFormsModule
:Files ASP.NET Core Blazor - MySolution.Blazor.Server\BlazorApplication.Designer.cs WinForms - MySolution.Win\WinApplication.Designer.cs
partial class MySolutionBlazorApplication { // ... private void InitializeComponent() { // this.module1 = new DevExpress.ExpressApp.SystemModule.SystemModule(); // this.module2 = new DevExpress.ExpressApp.Blazor.SystemModule.SystemBlazorModule(); // ... // this.Modules.Add(this.module1); // this.Modules.Add(this.module2); // ... // private DevExpress.ExpressApp.SystemModule.SystemModule module1; // private DevExpress.ExpressApp.Blazor.SystemModule.SystemBlazorModule module2; } }
Step 2. Implement an Application Builder in Your Project
In the Windows Forms application project, add a new file with the application builder:
File: MySolution.Win\Startup.cs.
using System; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Design; using DevExpress.ExpressApp.Win; using DevExpress.ExpressApp.Win.ApplicationBuilder; namespace MySolution.Win; public class ApplicationBuilder : IDesignTimeApplicationFactory { public static WinApplication BuildApplication(string connectionString) { ArgumentNullException.ThrowIfNull(connectionString); var builder = WinApplication.CreateBuilder(); builder.UseApplication<MySolutionWindowsFormsApplication>(); builder.Modules .Add<MySolutionWindowsFormsModule>(); builder.AddBuildStep(application => { application.ConnectionString = connectionString; }); var winApplication = builder.Build(); return winApplication; } XafApplication IDesignTimeApplicationFactory.Create() => BuildApplication(XafApplication.DesignTimeConnectionString); }
Use the application builder to create your WinForms or ASP.NET Core Blazor application:
WinForms: File: MySolution.Win\Program.cs.
static class Program { [STAThread] static void Main() { // Comment out or remove the following lines // var winApplication = new MySolutionWindowsFormsApplication(); // winApplication.GetSecurityStrategy().RegisterXPOAdapterProviders(); string connectionString = null; if(ConfigurationManager.ConnectionStrings["ConnectionString"] != null) { connectionString = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString; } ArgumentNullException.ThrowIfNull(connectionString); var winApplication = ApplicationBuilder.BuildApplication(connectionString); // ... } }
ASP.NET Core Blazor File: MySolution.Blazor.Server\Startup.cs.
using DevExpress.ExpressApp.ApplicationBuilder; using DevExpress.ExpressApp.Blazor.ApplicationBuilder; namespace MySolution.Blazor.Server; public class Startup { public Startup(IConfiguration configuration) { // ... // Comment out or remove the following line // services.AddXaf<MySolutionBlazorApplication>(Configuration); services.AddXaf(Configuration, builder => { builder.UseApplication<MySolutionBlazorApplication>(); builder.Modules .Add<MySolutionBlazorModule>(); }); // ... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... app.UseEndpoints(endpoints => { endpoints.MapXafEndpoints(); // ... }); } }
Step 3. Register Extra Modules in the Application Builder
Register and configure the required extra modules in your application builder. For example, to add Office, Dashboards, and Reports V2 modules to your application in the application builder, apply the following changes:
Comment out or remove the registration of modules from the
InitializeComponents
method:Files: ASP.NET Core Blazor - MySolution.Blazor.Server\BlazorApplication.Designer.cs WinForms - MySolution.Win\WinApplication.Designer.cs
private void InitializeComponent() { // this.module3 = new MySolution.Module.MySolutionModule(); // this.module4 = new MySolution.Module.Blazor.MySolutionBlazorModule(); // this.dashboardsModule = new DevExpress.ExpressApp.Dashboards.DashboardsModule(); // this.dashboardsBlazorModule = new DevExpress.ExpressApp.Dashboards.Blazor.DashboardsBlazorModule(); // this.officeModule = new DevExpress.ExpressApp.Office.OfficeModule(); // this.officeBlazorModule = new DevExpress.ExpressApp.Office.Blazor.OfficeBlazorModule(); // this.reportsModuleV2 = new DevExpress.ExpressApp.ReportsV2.ReportsModuleV2(); // this.reportsBlazorModuleV2 = new DevExpress.ExpressApp.ReportsV2.Blazor.ReportsBlazorModuleV2(); // ... // this.dashboardsModule.DashboardDataType = typeof(DevExpress.Persistent.BaseImpl.DashboardData); // this.reportsModuleV2.EnableInplaceReports = true; // this.reportsModuleV2.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2); // this.reportsModuleV2.ReportStoreMode = DevExpress.ExpressApp.ReportsV2.ReportStoreModes.XML; // ... // this.Modules.Add(this.module3); // this.Modules.Add(this.module4); // this.Modules.Add(this.dashboardsModule); // this.Modules.Add(this.dashboardsBlazorModule); // this.Modules.Add(this.officeModule); // this.Modules.Add(this.officeBlazorModule); // this.Modules.Add(this.reportsModuleV2); // this.Modules.Add(this.reportsBlazorModuleV2); // ... }
Use the Modules property and the “AddModuleName” methods (for example,
AddDashboards
orAddOffice
) to add the required modules to your application:ASP.NET Core Blazor File: MySolution.Blazor.Server\Startup.cs.
public void ConfigureServices(IServiceCollection services) { // ... services.AddXaf(Configuration, builder => { builder.UseApplication<MySolutionBlazorApplication>(); builder.Modules .Add<MySolutionBlazorModule>(); .AddOffice() .AddReports(options => { options.EnableInplaceReports = true; options.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2); options.ReportStoreMode = DevExpress.ExpressApp.ReportsV2.ReportStoreModes.XML; }) .AddDashboards(options => options.DashboardDataType = typeof(DevExpress.Persistent.BaseImpl.DashboardData)) // ... // ... }); // Comment out or remove the previously used registration code // services.AddXafReporting(); // services.AddXafDashboards(); // services.AddXafOffice(); // ... } public void Configure(IApplicationBuilder app, IWebHostEnvironment env) { // ... // app.UseDevExpressBlazorReporting(); app.UseEndpoints(endpoints => { // endpoints.MapXafDashboards(); // ... }); }
Note that with this technique, you do not need to add module-specific services, middleware, or endpoints explicitly (for example, you can remove such redundant methods as
services.AddXafOffice()
,app.UseDevExpressBlazorReporting()
, andendpoints.MapXafDashboards()
).WinForms File: MySolution.Win\Startup.cs.
using DevExpress.ExpressApp.Win.ApplicationBuilder; // ... public class ApplicationBuilder : IDesignTimeApplicationFactory { public static WinApplication BuildApplication(string connectionString) { // ... builder.Modules .Add<MySolutionWindowsFormsModule>() .AddOffice() .AddReports(options => { options.EnableInplaceReports = true; options.ReportDataType = typeof(DevExpress.Persistent.BaseImpl.ReportDataV2); options.ReportStoreMode = DevExpress.ExpressApp.ReportsV2.ReportStoreModes.XML; }) .AddDashboards(options => options.DashboardDataType = typeof(DevExpress.Persistent.BaseImpl.DashboardData) ); // ... } }
Step 4. Configure Object Space Providers
Comment out or remove the
CreateDefaultObjectSpaceProvider
method from your applications:Files: ASP.NET Core Blazor: MySolution.Blazor.Server\BlazorApplication.cs WinForms: MySolution.Win\WinApplication.cs
public partial class MySolutionBlazorApplication : BlazorApplication, ILegacyInitializationXafApplication { // ... // protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) { // ... // } }
According to your application configuration, use the following methods in your application builders to configure Object Space Providers:
- ASP.NET Core Blazor + XPO: AddXpo<TContext>(IObjectSpaceProviderServiceBasedBuilder<TContext>, Action<IServiceProvider, XPObjectSpaceProviderOptions>)
- ASP.NET Core Blazor + XPO + Security System: AddSecuredXpo<TContext>(IObjectSpaceProviderServiceBasedBuilder<TContext>, Action<IServiceProvider, XPObjectSpaceProviderOptions>)
- ASP.NET Core Blazor + EF Core: AddEFCore<TContext>(IObjectSpaceProviderServiceBasedBuilder<TContext>)
- ASP.NET Core Blazor + EF Core + Security System: AddSecuredEFCore<TContext>(IObjectSpaceProviderServiceBasedBuilder<TContext>)
- WinForms + XPO: AddXpo<TContext>(IObjectSpaceProviderBuilder<TContext>, Action<XafApplication, XPObjectSpaceProviderOptions>)
- WinForms + XPO + Security System: AddSecuredXpo<TContext>(IObjectSpaceProviderBuilder<TContext>, Action<XafApplication, XPObjectSpaceProviderOptions>)
- WinForms + EF Core: AddEFCore<TContext>(IObjectSpaceProviderBuilder<TContext>)
- WinForms + EF Core + Security System AddSecuredEFCore<TContext>(IObjectSpaceProviderBuilder<TContext>)
ASP.NET Core Blazor File: MySolution.Blazor.Server\Startup.cs.
public void ConfigureServices(IServiceCollection services) { // ... // services.AddSingleton<XpoDataStoreProviderAccessor>(); services.AddXaf(Configuration, builder => { // ... builder.ObjectSpaceProviders .AddSecuredXpo((serviceProvider, options) => { if (Configuration.GetConnectionString("ConnectionString") != null) { options.ConnectionString = Configuration.GetConnectionString("ConnectionString"); } #if EASYTEST if(Configuration.GetConnectionString("EasyTestConnectionString") != null) { options.ConnectionString = Configuration.GetConnectionString("EasyTestConnectionString"); } #endif options.ThreadSafe = true; options.UseSharedDataStoreProvider = true; }) .AddNonPersistent(); // ... }); }
WinForms File: MySolution.Win\Startup.cs.
public class ApplicationBuilder : IDesignTimeApplicationFactory { public static WinApplication BuildApplication(string connectionString) { // ... builder.ObjectSpaceProviders .AddSecuredXpo((application, options) => { options.ConnectionString = connectionString; }) .AddNonPersistent(); // ... } }
Step 5. Configure the Security System
In the application
InitializeComponent
method, comment out or remove SecurityModule registration and configuration of Security Strategy and authentication:Files: ASP.NET Core Blazor: MySolution.Blazor.Server\BlazorApplication.Designer.cs WinForms: MySolution.Win\WinApplication.Designer.cs
private void InitializeComponent() { // this.securityModule1 = new DevExpress.ExpressApp.Security.SecurityModule(); // this.securityStrategyComplex1 = new DevExpress.ExpressApp.Security.SecurityStrategyComplex(); // this.securityStrategyComplex1.SupportNavigationPermissionsForTypes = false; // this.authenticationStandard1 = new DevExpress.ExpressApp.Security.AuthenticationStandard(); // ... // this.securityStrategyComplex1.Authentication = this.authenticationStandard1; // this.securityStrategyComplex1.RoleType = typeof(DevExpress.Persistent.BaseImpl.PermissionPolicy.PermissionPolicyRole); // this.securityStrategyComplex1.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser); // this.securityModule1.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser); // this.authenticationStandard1.LogonParametersType = typeof(DevExpress.ExpressApp.Security.AuthenticationStandardLogonParameters); // this.authenticationStandard1.UserLoginInfoType = typeof(MySolution.Module.BusinessObjects.ApplicationUserLoginInfo); // ... // this.Modules.Add(this.securityModule1); // this.Security = this.securityStrategyComplex1; // ... }
In ASP.NET Core Blazor applications, comment out or remove the existing
AddXafSecurity
method call. To set up the Security System, use IBlazorSecurityBuilder.The following example demonstrates how to configure the application that uses the Security System in Integrated Mode with password authentication:
File: MySolution.Blazor.Server\Startup.cs.
public void ConfigureServices(IServiceCollection services) { // ... services.AddXaf(Configuration, builder => { // ... builder.Security .UseIntegratedMode(options => { options.RoleType = typeof(PermissionPolicyRole); options.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser); options.UserLoginInfoType = typeof(MySolution.Module.BusinessObjects.ApplicationUserLoginInfo); options.UseXpoPermissionsCaching(); }) .AddPasswordAuthentication(options => { options.IsSupportChangePassword = true; }) .AddExternalAuthentication(options => { }); // ... }); // services.AddXafSecurity(options => { // options.RoleType = typeof(PermissionPolicyRole); // options.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser); // options.UserLoginInfoType = typeof(MySolution.Module.BusinessObjects.ApplicationUserLoginInfo); // options.Events.OnSecurityStrategyCreated = securityStrategy => ((SecurityStrategy)securityStrategy).RegisterXPOAdapterProviders(); // options.SupportNavigationPermissionsForTypes = false; // }) // .AddAuthenticationStandard(options => { // options.IsSupportChangePassword = true; // }) // .AddExternalAuthentication<HttpContextPrincipalProvider>(); }
In WinForms applications, use IWinSecurityBuilder to set up the Security System.
The following example demonstrates how to configure the application that uses the Security System in Integrated Mode with password authentication:
File: MySolution.Win/Startup.cs.
using DevExpress.ExpressApp.ApplicationBuilder; using DevExpress.ExpressApp.Security; public class ApplicationBuilder : IDesignTimeApplicationFactory { public static WinApplication BuildApplication(string connectionString) { // ... builder.Security .UseIntegratedMode(options => { options.UserType = typeof(MySolution.Module.BusinessObjects.ApplicationUser); options.RoleType = typeof(DevExpress.Persistent.BaseImpl.PermissionPolicy.PermissionPolicyRole); options.UserLoginInfoType = typeof(MySolution.Module.BusinessObjects.ApplicationUserLoginInfo); options.UseXpoPermissionsCaching(); }) .UsePasswordAuthentication(options => { options.LogonParametersType = typeof(DevExpress.ExpressApp.Security.AuthenticationStandardLogonParameters); }); // ... } }
Step 6. Move Common Application Settings
Comment out or remove the remaining code from the
InitializeComponent
method:Files: ASP.NET Core Blazor: MySolution.Blazor.Server\BlazorApplication.Designer.cs WinForms: MySolution.Win\WinApplication.Designer.cs
private void InitializeComponent() { // ... // this.ApplicationName = "MySolution"; // this.CheckCompatibilityType = DevExpress.ExpressApp.CheckCompatibilityType.DatabaseSchema; // this.DatabaseVersionMismatch += new System.EventHandler<DevExpress.ExpressApp.DatabaseVersionMismatchEventArgs>(this.MySolutionBlazorApplication_DatabaseVersionMismatch); // ... }
Apply the commented settings in the application constructor or application builder’s AddBuildStep(Action<XafApplication>) method:
Files: ASP.NET Core Blazor - MySolution.Blazor.Server\BlazorApplication.cs WinForms - MySolution.Win\WinApplication.cs
public partial class MySolutionBlazorApplication : BlazorApplication, ILegacyInitializationXafApplication { public MySolutionBlazorApplication() { CheckCompatibilityType = DevExpress.ExpressApp.CheckCompatibilityType.DatabaseSchema; DatabaseVersionMismatch += MySolutionBlazorApplication_DatabaseVersionMismatch; } // ... }
ASP.NET Core Blazor File: MySolution.Blazor.Server\Startup.cs.
public void ConfigureServices(IServiceCollection services) { // ... services.AddXaf(Configuration, builder => { // ... builder.AddBuildStep(application => { application.ApplicationName = "MySolution"; }); }); // ... }
WinForms File: MySolution.Win\Startup.cs.
public class ApplicationBuilder : IDesignTimeApplicationFactory { public static WinApplication BuildApplication(string connectionString) { // ... builder.AddBuildStep(application => { application.ApplicationName = "MySolution"; }); // ... } }
Step 7. Remove Unnecessary Code and Files
You can remove the ILegacyInitializationXafApplication interface implementation from your applications and WinApplication.Designer.cs/BlazorApplication.Designer.cs files from your solution.