Execute Custom Operations on Endpoint Requests
- 3 minutes to read
You can add custom logic to methods that process HTTP requests. For this purpose, modify the built-in Data Service and register your custom implementation. This topic describes the basic steps you need to take:
Create a Custom Data Service
To implement a custom data service, create a class that extends the standard DataService
class available in the following namespace: DevExpress.ExpressApp.WebApi.Services
.
using DevExpress.Data.Filtering;
using DevExpress.ExpressApp.Core;
using DevExpress.ExpressApp.DC;
using DevExpress.ExpressApp.WebApi.Services;
// ...
public class CustomDataService : DataService {
public CustomDataService(IObjectSpaceFactory objectSpaceFactory,
ITypesInfo typesInfo) : base(objectSpaceFactory, typesInfo) { }
protected override T CreateObject<T>(IObjectDelta<T> delta,
IObjectSpace objectSpace) {
return base.CreateObject(delta, objectSpace);
}
}
Override Endpoint Methods
To customize an endpoint method in your custom data service, override the corresponding protected method of the base class and add your custom logic to the method’s implementation:
// GET
protected override IQueryable<T> GetObjectsQuery<T>(IObjectSpace objectSpace) {
if(typeof(T) == typeof(ApplicationUser)) {
// Custom logic
}
return base.GetObjectsQuery<T>();
}
// PATCH
protected override T PatchObject<T>(string key, IObjectDelta<T> delta,
IObjectSpace objectSpace) where T : class {
var original = GetObjectByKey<T>(key);
// Custom logic before modifications
delta.Patch(original);
// Custom logic after modifications
objectSpace.CommitChanges();
return original;
}
// ...
Access Object Space
The base DataService
class manages Object Spaces internally and passes their correct instances to overridden methods based on the generic type parameter:
// The method receives an Object Space for the type T
protected override IQueryable<T> GetObjectsQuery<T>(IObjectSpace objectSpace) { /** **/ }
To get an Object Space for a type that is unrelated to the current method, call the base class’s GetObjectSpace<T>
method:
var userObjectSpace = GetObjectSpace<User>();
Keep in mind that you should not manually dispose of Object Spaces obtained through GetObjectSpace
. The data service correctly disposes of them in the base Dispose
method implementation.
If required, you can also use the IObjectSpaceFactory
available through the data service class constructor to create a new Object Space. In this case, it is your responsibility to dispose of the created Object Space. To do it safely, we recommend that you override the data service’s base Dispose
method and use it to call the Dispose
method for all manually created Object Spaces.
public class CustomDataService : DataService {
private readonly IObjectSpace myTypeObjectSpace;
public CustomDataService(IObjectSpaceFactory objectSpaceFactory, ITypesInfo typesInfo) : base(objectSpaceFactory, typesInfo) {
myTypeObjectSpace = objectSpaceFactory.CreateObjectSpace(typeof(MyType));
}
// ...
public override void Dispose() {
base.Dispose();
myTypeObjectSpace.Dispose();
}
}
Register Your Custom Data Service
Use the code below to register your custom data service. Add the registration line to the ConfigureServices
method, after the AddXafWebApi()
method call.
File: MySolution.WebApi\Startup.cs (MySolution.Blazor.Server\Startup.cs)
namespace MySolution.WebApi {
public class Startup {
// ...
public void ConfigureServices(IServiceCollection services) {
services.AddXafWebApi(builder => {
// In XPO applications, uncomment the following line:
// builder.AddXpoServices();
// ...
}, Configuration);
services.AddScoped<IDataService, CustomDataService>();
}
// ...
}
}