.NET Framework 4.5.2+
.NET Framework 4.5.2+
.NET Standard 2.0+
.NET 5.0+

IRuleSource Interface

Declares members that custom Validation Rule Sources implement.

Namespace: DevExpress.Persistent.Validation

Assembly: DevExpress.Persistent.Base.v21.2.dll


public interface IRuleSource


Implement the IRuleSource interface in your business class to create a custom Validation Rule Source. Custom Validation Rule Sources allows you to store Validation Rules in the database. We recommend that you use this technique if you need to frequently customize Validation Rules in a deployed application, but you cannot redeploy the application or customize its Application Model. Refer to the following help topic for information on other techniques to declare Validation Rules: Declare Validation Rules.

The IRuleSource interface declares the following members:

IRuleSource.Name property
Returns the unique name of the custom Validation Rule Source.
IRuleSource.CreateRules method
Instantiates custom Validation Rules.

The Validation Module automatically collects persistent Validation Rule Sources and Rules when you start an application. Persistent Validation Rule Sources and Rules are persistent classes that implement the IRuleSource and IRule interfaces accordingly. Built-in Rule Sources query the database each time before validation occurs. Use the EnableRuntimeRuleCache property to enable Rule caching for all persistent Rule Sources. You can also disable automatic collection of persistent Rules and Rule Sources and add custom proxy Rule Sources with different behavior. To see the example of how to do this, refer to the following property description: EnableRuntimeRuleDiscovery.


The following example demonstrates how to create a custom persistent Validation Rule Source:

  1. Create a new class (RuleRequiredFieldPersistent) and implement the IRuleSource interface in it.
  2. Apply DefaultClassOptionsAttribute to this class to allow users to create Validation Rules at runtime.
  3. In the IRuleSource.CreateRules method, create a RuleRequiredField Validation Rule based on the values of the RuleRequiredFieldPersistent class’ public properties.


A complete sample project is available in the DevExpress Code Examples database at https://supportcenter.devexpress.com/ticket/details/e729/how-to-create-validation-rules-stored-in-the-database.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
using DevExpress.Persistent.Base;
using DevExpress.Persistent.BaseImpl;
using DevExpress.Persistent.Validation;
using DevExpress.Xpo;
// ...
public class RuleRequiredFieldPersistent : BaseObject, IRuleSource {
    public RuleRequiredFieldPersistent(Session session) : base(session) { }
    public string RuleName {
        get { return GetPropertyValue<string>(nameof(RuleName)); }
        set { SetPropertyValue(nameof(RuleName), value); }
    public string CustomMessageTemplate {
        get { return GetPropertyValue<string>(nameof(CustomMessageTemplate)); }
        set { SetPropertyValue(nameof(CustomMessageTemplate), value); }
    public bool SkipNullOrEmptyValues {
        get { return GetPropertyValue<bool>(nameof(SkipNullOrEmptyValues)); }
        set { SetPropertyValue(nameof(SkipNullOrEmptyValues), value); }
    public string Id {
        get { return GetPropertyValue<string>(nameof(Id)); }
        set { SetPropertyValue(nameof(Id), value); }
    public bool InvertResult {
        get { return GetPropertyValue<bool>(nameof(InvertResult)); }
        set { SetPropertyValue(nameof(InvertResult), value); }
    public string ContextIDs {
        get { return GetPropertyValue<string>(nameof(ContextIDs)); }
        set { SetPropertyValue(nameof(ContextIDs), value); }
    public string Property {
        get { return GetPropertyValue<string>(nameof(Property)); }
        set { SetPropertyValue(nameof(Property), value); }
    protected string ObjectType {
        get {
            if (ObjectTypeCore != null) {
                return ObjectTypeCore.FullName;
            return "";
        set { ObjectTypeCore = ReflectionHelper.FindType(value); }
    public Type ObjectTypeCore {
        get { return GetPropertyValue<Type>(nameof(ObjectTypeCore)); }
        set { SetPropertyValue(nameof(ObjectTypeCore), value); }
    #region IRuleSource Members
    public ICollection<IRule> CreateRules() {
        List<IRule> list = new List<IRule>();
        RuleRequiredField rule = new RuleRequiredField();
        rule.Properties.SkipNullOrEmptyValues = this.SkipNullOrEmptyValues;
        rule.Properties.Id = this.Id;
        rule.Properties.InvertResult = this.InvertResult;
        rule.Properties.CustomMessageTemplate = this.CustomMessageTemplate;
        rule.Properties.TargetContextIDs = this.ContextIDs;
        rule.Properties.TargetType = this.ObjectTypeCore;
        if (rule.Properties.TargetType != null) {
            foreach (PropertyInfo pi in rule.Properties.TargetType.GetProperties()) {
                if (pi.Name == this.Property) {
                    rule.Properties.TargetPropertyName = pi.Name;
        for (int i = Validator.RuleSet.RegisteredRules.Count - 1; i >= 0; i--) {
            if (Validator.RuleSet.RegisteredRules[i].Id == this.Id) {
        return list;
    public string Name {
        get { return this.RuleName; }

The following code snippet (auto-collected from DevExpress Examples) contains a reference to the IRuleSource interface.


The algorithm used to collect these code examples remains a work in progress. Accordingly, the links and snippets below may produce inaccurate results. If you encounter an issue with code examples below, please use the feedback form on this page to report the issue.

See Also