Skip to main content
All docs
V23.2

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

  1. 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.

  2. In the InitializeComponent method, comment out the registration of SystemModule, SystemBlazorModule, and SystemWindowsFormsModule:

    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

  1. 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);
    }
    
  2. 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:

  1. 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);
    
        // ...
    }
    
  2. Use the Modules property and the “AddModuleName” methods (for example, AddDashboards or AddOffice) 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(), and endpoints.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)
                );
            // ...
        }
    }
    

Note

If your application has a customized module-specific exported type (a business class that the Application Model must load), specify this type in the Application Builder module options in the following manner:

using DevExpress.ExpressApp.ApplicationBuilder;
using DevExpress.ExpressApp.Blazor.ApplicationBuilder;
using DevExpress.Persistent.BaseImpl;

namespace YourApplicationName.Blazor.Server;

public class Startup {
   // ...
    public void ConfigureServices(IServiceCollection services) {
        // ...
        services.AddXaf(Configuration, builder => {
            builder.UseApplication<MySolutionBlazorApplication>();
            builder.Modules
                // ...
                builder.Modules
                    .AddReports(options => {
                        options.ReportDataType = typeof(MyReportDataV2);
                    })
                    .AddScheduler(options => {
                        options.ExportedTypes.Clear();
                        options.ExportedTypes.Add(typeof(MyEvent));
                        options.ExportedTypes.Add(typeof(MyResource));
                    })
                    .AddFileAttachments(options => {
                        options.ExportedTypes.Clear();
                        options.ExportedTypes.Add(typeof(MyFileDate));
                        options.ExportedTypes.Add(typeof(MyFileAttachment));
                    })
            // ...
        });
        // ...
    }
}

Step 4. Configure Object Space Providers

  1. 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) {
        // ...
        // }
    }
    
  2. According to your application configuration, use the following methods in your application builders to configure Object Space Providers:

    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

  1. 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;
    
        // ...
    }
    
  2. 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>();
    }
    
  3. 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

  1. 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);
        // ...
    }
    
  2. 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.