.NET Core 3.0+
.NET Framework 4.5.2+
.NET Standard 2.0+
.NET Core 3.0+

IXafEntityObject Interface

Declares methods that are called automatically when a business object is being created, loaded and saved.

Namespace: DevExpress.ExpressApp

Assembly: DevExpress.ExpressApp.v20.2.dll

Declaration

public interface IXafEntityObject
Public Interface IXafEntityObject

Remarks

When a business object supports IXafEntityObject, the Object Space automatically calls the IXafEntityObject.OnCreated, IXafEntityObject.OnLoaded and IXafEntityObject.OnSaving methods of this interface when an object is being created, loaded and saved. Thus, you can implement these methods and add certain business logic directly in the business object code, without the use of Controllers. In most cases, you may need to access other business objects from your code, so you can implement the IObjectSpaceLink interface to access an IObjectSpace instance and use its methods to query objects.

NOTE
  • The IXafEntityObject interface is intended for use with Entity Framework and Non-Persistent Objects. For eXpress Persistent Objects (XPO), use the BaseObject.AfterConstruction and BaseObject.OnSaving methods.
  • You can use the XAF Business Object | EF Business Object from Template Gallery to add a class that supports both IXafEntityObject and IObjectSpaceLink.

In the example below, the CreatedBy property refers to the user who created the current object, the LastModifiedBy property specifies the user who last changed the object, and the IsNew property indicates if an object is only created, but not saved. For example, you can use this property in Conditional Appearance and Validation rules.

using System.ComponentModel;
using System.ComponentModel.DataAnnotations.Schema;
using DevExpress.ExpressApp;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl.EF.PermissionPolicy;
// ...
[DefaultClassOptions]
public class MyEntityObject : IXafEntityObject, IObjectSpaceLink {
    [Browsable(false)]
    public Int32 ID { get; protected set; }
    public string Name { get; set; }
    [NotMapped]
    public bool IsNew { get; protected set; }
    public virtual PermissionPolicyUser CreatedBy { get; protected set; }
    public virtual PermissionPolicyUser LastModifiedBy { get; protected set; }
    PermissionPolicyUser GetCurrentUser() {
        return objectSpace.GetObjectByKey<PermissionPolicyUser>(SecuritySystem.CurrentUserId);
    }
    #region IXafEntityObject members
    void IXafEntityObject.OnCreated() {
        CreatedBy = GetCurrentUser();
        IsNew = true;
    }
    void IXafEntityObject.OnLoaded() {
        IsNew = false;
    }
    void IXafEntityObject.OnSaving() {
        if (objectSpace != null) {
            LastModifiedBy = GetCurrentUser();
        }
        IsNew = false;
    }
    #endregion
    #region IObjectSpaceLink members
    private IObjectSpace objectSpace;
    IObjectSpace IObjectSpaceLink.ObjectSpace {
        get { return objectSpace; }
        set { objectSpace = value; }
    }
    #endregion
}

Note that in the OnSaving method, you need to check if an Object Space is null (Nothing in VB). The reason is that the OnSaving method is also called when the current business object is being deleted and the link to the Object Space is already cleared at that moment to avoid memory leaks. If you want to access the Object Space on object deletion, change the IObjectSpaceLink.ObjectSpace property implementation to maintain the Object Space reference.

private IObjectSpace objectSpace;
IObjectSpace IObjectSpaceLink.ObjectSpace {
    get { return objectSpace; }
    set { if (value != null) objectSpace = value; }
}

In this instance, you should manually set the Object Space to null (Nothing in VB) on deletion. Use the IObjectSpace.IsObjectToDelete method to determine whether an object is being saved or deleted:

void IXafEntityObject.OnSaving() {
    PermissionPolicyUser currentUser = objectSpace.GetObjectByKey<PermissionPolicyUser>(SecuritySystem.CurrentUserId);
    if (objectSpace.IsObjectToDelete(this)) {
        // Executed on deletion:
        Tracing.Tracer.LogWarning("The '{0}' user is deleting the '{1}' object", currentUser.UserName, Name);
        objectSpace = null; 
    }
    else {
        // Executed on saving:
        LastModifiedBy = currentUser;
    }
}
See Also