KB Article T591324
Visible to All Users

How to customize the UnitOfWork behavior in XPO-based XAF applications

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 Basic
Imports 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 Basic
Imports 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 Basic
Protected 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 Basic
Imports 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 Basic
Imports 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 Basic
Dim serviceHost As New CustomWcfServiceHost(connectionString, dataServerSecurityProvider)

See also:
T590896: How to customize the Object Space behavior in XPO-based XAF applications

Disclaimer: The information provided on DevExpress.com and affiliated web properties (including the DevExpress Support Center) is provided "as is" without warranty of any kind. Developer Express Inc disclaims all warranties, either express or implied, including the warranties of merchantability and fitness for a particular purpose. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.

Confidential Information: Developer Express Inc does not wish to receive, will not act to procure, nor will it solicit, confidential or proprietary materials and information from you through the DevExpress Support Center or its web properties. Any and all materials or information divulged during chats, email communications, online discussions, Support Center tickets, or made available to Developer Express Inc in any manner will be deemed NOT to be confidential by Developer Express Inc. Please refer to the DevExpress.com Website Terms of Use for more information in this regard.