How to: Display Non-Persistent Objects in a Report
- 3 minutes to read
This topic describes how to create a report based on non-persistent data. Use this approach to analyze and report data obtained from runtime calculations, stored procedures, arbitrary SQL queries, or third-party services.
Create a Report and Bind It to a Non-Persistent Data Type
Declare a non-persistent class (for example,
MyNonPersistentObject), and decorate it with the DomainComponent and VisibleInReports attributes.using DevExpress.ExpressApp.DC; using DevExpress.Persistent.Base; // ... [DomainComponent, VisibleInReports] public class MyNonPersistentObject : NonPersistentBaseObject { public string Name { get; set; } }Create a report for the
MyNonPersistentObjectdata type. You can add a predefined static report in Visual Studio or create a report at runtime.
Important
Non-persistent objects do not support the ViewDataSource component – use CollectionDataSource to bind a report to data.
At this step, the created report displays no data in the preview.

Supply the Report with Data (Initialize Non-Persistent Objects)
Use the Application Builder
In the Application Builder code, handle the NonPersistentObjectSpace.ObjectsGetting event as shown below:
File: MySolution.Blazor.Server\Startup.cs, MySolution.Win\Startup.cs
using System.ComponentModel;
using DevExpress.ExpressApp;
using DevExpress.ExpressApp.Core;
// ...
// Handle the `NonPersistentObjectSpace.ObjectsGetting` event.
builder.ObjectSpaceProviders.Events.OnObjectSpaceCreated = context => {
if (context.ObjectSpace is NonPersistentObjectSpace nonPersistentObjectSpace) {
nonPersistentObjectSpace.ObjectsGetting += NonPersistentObjectSpace_ObjectsGetting;
}
};
// ...
private static void NonPersistentObjectSpace_ObjectsGetting(object sender, ObjectsGettingEventArgs e) {
// In the event handler, populate the `e.Objects` collection
// with non-persistent objects of the required type.
if (e.ObjectType == typeof(MyNonPersistentObject)) {
BindingList<MyNonPersistentObject> objects = new BindingList<MyNonPersistentObject>();
for (int i = 1; i < 10; i++) {
objects.Add(new MyNonPersistentObject() { Name = string.Format("Object {0}", i) });
}
e.Objects = objects;
}
}
// ...
Implement an IObjectSpaceCustomizer
In the module project, implement the
IObjectSpaceCustomizerservice as shown below:File: MySolution.Module\NonPersistentObjectSpaceCustomizer.cs
using System.ComponentModel; using DevExpress.ExpressApp; using DevExpress.ExpressApp.Core; public class NonPersistentObjectSpaceCustomizer : IObjectSpaceCustomizer { private readonly IObjectSpaceProviderService objectSpaceProvider; private readonly IObjectSpaceCustomizerService objectSpaceCustomizerService; public NonPersistentObjectSpaceCustomizer( IObjectSpaceProviderService objectSpaceProvider, IObjectSpaceCustomizerService objectSpaceCustomizerService) { this.objectSpaceProvider = objectSpaceProvider; this.objectSpaceCustomizerService = objectSpaceCustomizerService; } public void OnObjectSpaceCreated(IObjectSpace objectSpace) { if(objectSpace is NonPersistentObjectSpace nonPersistentObjectSpace) { // Handle the `NonPersistentObjectSpace.ObjectsGetting` event. nonPersistentObjectSpace.ObjectsGetting += NonPersistentObjectSpace_ObjectsGetting; nonPersistentObjectSpace.ObjectByKeyGetting += NonPersistentObjectSpace_ObjectByKeyGetting; nonPersistentObjectSpace.Committing += NonPersistentObjectSpace_Committing; nonPersistentObjectSpace.PopulateAdditionalObjectSpaces(objectSpaceProvider, objectSpaceCustomizerService); } } private void NonPersistentObjectSpace_ObjectsGetting(object? sender, ObjectsGettingEventArgs e) { // In the event handler, populate the `e.Objects` collection // with non-persistent objects of the required type. if (e.ObjectType == typeof(MyNonPersistentObject)) { BindingList<MyNonPersistentObject> objects = new BindingList<MyNonPersistentObject>(); for (int i = 1; i < 10; i++) { objects.Add(new MyNonPersistentObject() { Name = string.Format("Object {0}", i) }); } e.Objects = objects; } } private void NonPersistentObjectSpace_ObjectByKeyGetting(object? sender, ObjectByKeyGettingEventArgs e) { //... } private void NonPersistentObjectSpace_Committing(object? sender, CancelEventArgs e) { //... } }Register your
IObjectSpaceCustomizerservice implementation in the Starup.cs file of the Blazor and WinForms applications. Use the TryAddEnumerable method to register these services:File: MySolution.Blazor.Server\Startup.cs, MySolution.Win\Startup.cs
public void ConfigureServices(IServiceCollection services) { //... services.TryAddEnumerable(ServiceDescriptor.Scoped<IObjectSpaceCustomizer, NonPersistentObjectSpaceCustomizer>()); //... }
The following image demonstrates the result:
