views:

138

answers:

3

Is there a standard convention when designing business objects for providing consumers with a way to discover constraints such as a property's maximum length?

It could be used up in the UI layer to, for example, set a Textbox's MaxLength property according to the maximum length limit back in the business object.

Is there a standard design approach for this?

+1  A: 

Validation frameworks often contain parts for integrating with UI technologies in communicating the errors. Microsoft Enterprise Library Validation Application Block for instance contains a ValidationProvider extender control for WinForms that binds with the WinForms ErrorProvider control.

Your wish is different though. You want to communicate the constraints before they turn in to errors. Because this is not a standard requirement, I don't believe most validation frameworks have something for this out of the box. However, depending on the chosen framework creating this might be achievable. The Validation Application Block for instance, allows you to analyze the rules that you have registered / configured on a entity. So it is possible to build a control that will do this for you.

[Edit] What you could also do is validate a form immediately upon startup and after each keystroke. This causes error icons or messages to show up immediately, which allows users to directly see what the constraints are (when you use icons, the user can hover an icon to see the error message). This isn't perhaps as nice as creating your own control, but it much easier to implement.

Steven
A: 

I have my own validation framework that lets me validate each field with the help of designated ValidationAttribute. It uses Attributes to automate most of the validations.

A sample business object would look like this in my application.

Each business object would inherit from EntityBase abstract class that has a public method called "Validate()". When this method is called on the given instance of the business object it will iterate through all properties of its own having Attributes that are derived from ValidationAttribute can call ValidationAttriubte's IsValid method to validate the value of associated proerty and return true/false with err. msg if any.

User.cs

[TableMapping("Users")]
public class User : EntityBase
{
    #region Constructor(s)
    public AppUser()
    {
        BookCollection = new BookCollection();
    }
    #endregion

    #region Properties

    #region Default Properties - Direct Field Mapping using DataFieldMappingAttribute

    private System.Int32 _UserId;

    private System.String _FirstName;
    private System.String _LastName;
    private System.String _UserName;
    private System.Boolean _IsActive;

    [DataFieldMapping("UserID")]
    [DataObjectFieldAttribute(true, true, false)]
    [NotNullOrEmpty(Message = "UserID From Users Table Is Required.")] // VALIDATION ATTRIBUTE
    public override int Id
    {
        get
        {
            return _UserId;
        }
        set
        {
            _UserId = value;
        }
    }

    [DataFieldMapping("UserName")]
    [Searchable]
    [NotNullOrEmpty(Message = "Username Is Required.")] // VALIDATION ATTRIBUTE

    public string UserName
    {
        get
        {
            return _UserName;
        }
        set
        {
            _UserName = value;
        }
    }

    [DataFieldMapping("FirstName")]
    [Searchable]
    public string FirstName
    {
        get
        {
            return _FirstName;
        }
        set
        {
            _FirstName = value;
        }
    }

    [DataFieldMapping("LastName")]
    [Searchable]
    public string LastName
    {
        get
        {
            return _LastName;
        }
        set
        {
            _LastName = value;
        }
    }

    [DataFieldMapping("IsActive")]
    public bool IsActive
    {
        get
        {
            return _IsActive;
        }
        set
        {
            _IsActive = value;
        }
    }

    #region One-To-Many Mappings
    public BookCollection Books { get; set; }

    #endregion

    #region Derived Properties
    public string FullName { get { return this.FirstName + " " + this.LastName; } }

    #endregion

    #endregion

    public override bool Validate()
    {
        bool baseValid = base.Validate();
        bool localValid = Books.Validate();
        return baseValid && localValid;
    }
}

BookCollection.cs

/// <summary>
/// The BookCollection class is designed to work with lists of instances of Book.
/// </summary>
public class BookCollection : EntityCollectionBase<Book>
{
    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection()
    {
    }

    /// <summary>
    /// Initializes a new instance of the BookCollection class.
    /// </summary>
    public BookCollection (IList<Book> initialList)
        : base(initialList)
    {
    }
}
this. __curious_geek
I'm afraid this doesn't really answer his question, because he likes to show the user the list of business rules before things got validated. Not how to validate.
Steven
A: 

Custom Attributes might serve your need.

matt eisenberg