This article describes how to create a custom Unit of Work class and use it within a custom Object Space Provider. The following code examples are available starting with version 17.2.6.
1. Inherit UnitOfWork and override one or more protected methods you want to customize, e.g., the GetPropertiesListForUpdateInsert method.
C#using DevExpress.Xpo;
using DevExpress.Xpo.Metadata.Helpers;
// ...
public class CustomUnitOfWork : UnitOfWork {
public CustomUnitOfWork(IDataLayer dataLayer) : base(dataLayer) { }
protected override MemberInfoCollection GetPropertiesListForUpdateInsert(object theObject, bool isUpdate, bool addDelayedReference) {
// Write your custom code here, or override other methods.
return base.GetPropertiesListForUpdateInsert(theObject, isUpdate, addDelayedReference);
}
}
Visual BasicImports DevExpress.Xpo
Imports DevExpress.Xpo.Metadata.Helpers
' ...
Public Class CustomUnitOfWork
Inherits UnitOfWork
Public Sub New(ByVal dataLayer As IDataLayer)
MyBase.New(dataLayer)
End Sub
Protected Overrides Function GetPropertiesListForUpdateInsert(ByVal theObject As Object, ByVal isUpdate As Boolean, ByVal addDelayedReference As Boolean) As MemberInfoCollection
' Write your custom code here, or override other methods.
Return MyBase.GetPropertiesListForUpdateInsert(theObject, isUpdate, addDelayedReference)
End Function
End Class
2. Inherit XPObjectSpaceProvider, override the CreateUnitOfWork method and return your CustomUnitOfWork instance in this method. If you use the Integrated Mode of the Security System, inherit SecuredObjectSpaceProvider instead of XPObjectSpaceProvider and override CreateDirectUnitOfWork method instead of CreateUnitOfWork.
C#using System.Data;
using DevExpress.Xpo;
using DevExpress.ExpressApp.Xpo;
// ...
public class CustomXPObjectSpaceProvider : XPObjectSpaceProvider {
public CustomXPObjectSpaceProvider(string connectionString, IDbConnection connection) :
base(connectionString, connection) { }
protected override UnitOfWork CreateUnitOfWork(IDataLayer dataLayer) {
return new CustomUnitOfWork(dataLayer);
}
}
Visual BasicImports System.Data
Imports DevExpress.Xpo
Imports DevExpress.ExpressApp.Xpo
' ...
Public Class CustomXPObjectSpaceProvider
Inherits XPObjectSpaceProvider
Public Sub New(ByVal connectionString As String, ByVal connection As IDbConnection)
MyBase.New(connectionString, connection)
End Sub
Protected Overrides Function CreateUnitOfWork(ByVal dataLayer As IDataLayer) As UnitOfWork
Return New CustomUnitOfWork(dataLayer)
End Function
End Class
3. In the application project, edit the WinApplication.cs (WinApplication.vb) or WebApplication.cs (WebApplication.vb) file. In the CreateDefaultObjectSpaceProvider method, add the CustomXPObjectSpaceProvider instance to the ObjectSpaceProviders list:
C#protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) {
// ...
args.ObjectSpaceProviders.Add(new CustomXPObjectSpaceProvider(args.ConnectionString, args.Connection));
}
Visual BasicProtected Overrides Sub CreateDefaultObjectSpaceProvider(ByVal args As CreateCustomObjectSpaceProviderEventArgs)
' ...
args.ObjectSpaceProviders.Add(New CustomXPObjectSpaceProvider(args.ConnectionString, args.Connection))
End Sub
Middle Tier Specifics
If you use the Middle Tier Security, you should additionally do the following:
1. In the server project, inherit the WcfSecuredServer class, override the CreateUnitOfWork method and return the CustomUnitOfWork instance in this method.
C#using DevExpress.Xpo;
using DevExpress.ExpressApp.Security.ClientServer;
// ...
public class CustomWcfSecuredServer : WcfSecuredServer {
public CustomWcfSecuredServer(
IDataLayer dataLayer, IDataServerSecurity serverSecurity, bool allowICommandChannelDoWithSecurityContext, InstanceContextMode contextMode) :
base(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode) { }
protected override UnitOfWork CreateUnitOfWork(IDataLayer dataLayer) {
return new CustomUnitOfWork(dataLayer);
}
}
Visual BasicImports DevExpress.Xpo
Imports DevExpress.ExpressApp.Security.ClientServer
' ...
Public Class CustomWcfSecuredServer
Inherits WcfSecuredServer
Public Sub New(ByVal dataLayer As IDataLayer, ByVal serverSecurity As IDataServerSecurity, _
ByVal allowICommandChannelDoWithSecurityContext As Boolean, ByVal contextMode As InstanceContextMode)
MyBase.New(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode)
End Sub
Protected Overrides Function CreateUnitOfWork(ByVal dataLayer As IDataLayer) As UnitOfWork
Return New CustomUnitOfWork(dataLayer)
End Function
End Class
2. Inherit WcfXafServiceHost, override the GetInstanceCore method and return the CustomWcfSecuredServer instance in this method.
C#using DevExpress.Xpo;
using DevExpress.ExpressApp.Security.ClientServer;
// ...
public class CustomWcfServiceHost : WcfXafServiceHost {
public CustomWcfServiceHost(string connectionString, Func<IDataServerSecurity> dataServerSecurity) :
base(connectionString, dataServerSecurity) { }
protected override object GetInstanceCore(InstanceContext instanceContext, Message message, IDataLayer dataLayer,
IDataServerSecurity serverSecurity, bool allowICommandChannelDoWithSecurityContext, InstanceContextMode contextMode) {
return new CustomWcfSecuredServer(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode);
}
}
Visual BasicImports DevExpress.Xpo
Imports DevExpress.ExpressApp.Security.ClientServer
' ...
Public Class CustomWcfServiceHost
Inherits WcfXafServiceHost
Public Sub New(ByVal connectionString As String, ByVal dataServerSecurity As Func(Of IDataServerSecurity))
MyBase.New(connectionString, dataServerSecurity)
End Sub
Protected Overrides Function GetInstanceCore(ByVal instanceContext As InstanceContext, ByVal message As Message, _
ByVal dataLayer As IDataLayer, ByVal serverSecurity As IDataServerSecurity, ByVal allowICommandChannelDoWithSecurityContext As Boolean, _
ByVal contextMode As InstanceContextMode) As Object
Return New CustomWcfSecuredServer(dataLayer, serverSecurity, allowICommandChannelDoWithSecurityContext, contextMode)
End Function
End Class
3. In the Program.cs(Program.vb) file of the server application, find the line where the serviceHost variable is initialized. Replace the WcfXafServiceHost type with CustomWcfServiceHost.
C#CustomWcfServiceHost serviceHost = new CustomWcfServiceHost(connectionString, dataServerSecurityProvider);
Visual BasicDim serviceHost As New CustomWcfServiceHost(connectionString, dataServerSecurityProvider)
See also:
T590896: How to customize the Object Space behavior in XPO-based XAF applications