Common Reusable Business Entities Part 3

This is part two of an ongoing series on common reusable business entities. This series does not need to be read in order, but here are the preceeding posts if you would like to catch up:

This will be the final article in a three part series regarding Common Business Entities. The original hope was to provide a a few common business objects that are used across most business-style applications. Additionally, I hoped to demonstrate at least a skeleton of business entitities that those unfamiliar with custom object creation could begin playing with.

In this article, we’ll cover a few important numbers; such as the CreditCardNumber, SocialSecurityNumber, and PhoneNumber objects. The structures do not have a lot of business logic (such as validation), because I am attempting to demonstrate very lean entities (as recently seen in WCF-style applications) and leave the logic up to the business layer to be called upon. If you chose to use these objects in your own application, please ensure you add validation as you could see unexpected results.

So let’s get to it:

CreditCardNumber Structure

public struct CreditCardNumber
{
    #region "PROPERTIES"

    /// <summary>
    /// The type of credit card (VISA, Mastercard, etc.).
    /// </summary>
    public enum CreditCardType
    {
        VISA,
        Mastercard,
        AmericanExpress,
        Discover
    }

    /// <summary>
    /// The credit card number without any formatting.
    /// </summary>
    public string Value { get; set; }

    /// <summary>
    /// The type of credit card (VISA, Mastercard, etc.).
    /// </summary>
    public CreditCardType Type { get; set; }

    /// <summary>
    /// The secure credit card CVV number.
    /// </summary>
    public int? CVV { get; set; }  //123

    /// <summary>
    /// The expiration month of the credit card as a two digit integer.
    /// </summary>
    public int ExpirationMonth { get; set; }  //12    //NOTE: This could be an enum or it's own object (Month), but for simplicity I am just showing an integer

    /// <summary>
    /// The expiration year of the credit card as a four digit integer.
    /// </summary>
    public int ExpirationYear { get; set; }  //2009

    /// <summary>
    /// The masked credit card number.
    /// </summary>
    public string Masked  //XXXXXXXXXXXX1234
    {
        get
        {
            string result = string.Empty;

            if (!string.IsNullOrEmpty(Value))
            {
                int length = Value.Length;
                string suffix = Value.Substring(length - 4, 4);
                return string.Format("XXXXXXXXXXXX{0}", suffix);
            }

            return result;
        }
    }

    #endregion

    #region "CONSTRUCTORS"

    /// <summary>
    /// Create a new credit card number.
    /// </summary>
    /// <param name="value"></param>
    /// <param name="expirationMonth"></param>
    /// <param name="expirationYear"></param>
    /// <param name="creditCardType"></param>
    public CreditCardNumber(string value, int expirationMonth, int expirationYear, CreditCardType creditCardType) : this()
    {
        Value = value;
        ExpirationMonth = expirationMonth;
        ExpirationYear = expirationYear;
        this.Type = creditCardType;
    }

    /// <summary>
    /// Create a new credit card number.
    /// </summary>
    /// <param name="value"></param>
    /// <param name="expirationMonth"></param>
    /// <param name="expirationYear"></param>
    /// <param name="creditCardType"></param>
    /// <param name="cvv"></param>
    public CreditCardNumber(string value, int expirationMonth, int expirationYear, CreditCardType creditCardType, int? cvv) : this()
    {
        Value = value;
        ExpirationMonth = expirationMonth;
        ExpirationYear = expirationYear;
        this.Type = creditCardType;
        CVV = cvv;
    }

    #endregion
}

SocialSecurityNumber Structure

public struct SocialSecurityNumber
{
    #region "PROPERTIES"

    /// <summary>
    /// The social security number without any formatting.
    /// </summary>
    public string Value { get; set; } //123121234

    /// <summary>
    /// A masked version of the social security number.
    /// </summary>
    public string Masked  //XXX-XX-1234
    {
        get
        {
            string result = string.Empty;

            if(Value.Length == 9)
            {
                result = string.Format("XXX-XX-{0}", Value.Substring(4, 4));
            }

            return result;
        }
    }

    #endregion

    #region "CONSTRUCTORS"

    /// <summary>
    /// Create a new social security number.
    /// </summary>
    /// <param name="value"></param>
    public SocialSecurityNumber(string value)
    {
        Value = value;
    }

    #endregion
}

PhoneNumber Structure

public struct PhoneNumber
{
    #region "PROPERTIES"

    /// <summary>
    /// The phone number without any formatting.
    /// </summary>
    public string Value { get; set; } //2395551234

    /// <summary>
    /// The areacode of the phone number.
    /// </summary>
    public string Areacode //239
    {
        get
        {
            string result = string.Empty;

            if(Value.Length == 10)
            {
                result = Value.Substring(0, 3);
            }

            return result;
        }
    }

    /// <summary>
    /// The prefix of the phone number.
    /// </summary>
    public string Prefix //555
    {
        get
        {
            string result = string.Empty;

            if(Value.Length == 10)
            {
                result = Value.Substring(3, 3);
            }

            return result;
        }
    } 

    /// <summary>
    /// The suffix of the phone number.
    /// </summary>
    public string Suffix //1234
    {
        get
        {
            string result = string.Empty;

            if(Value.Length == 10)
            {
                result = Value.Substring(6, 4);
            }

            return result;
        }
    } 

    /// <summary>
    /// The masked phone number.
    /// </summary>
    public string Masked //(XXX)XXX-1234
    {
        get
        {
            string result = string.Empty;

            if(Value.Length == 10)
            {
                result = string.Format("(XXX)XXX-{0}", Suffix);
            }

            return result;
        }
    }

    #endregion

    #region "CONSTRUCTORS"

    public PhoneNumber(string value) : this()
    {
        Value = value;
    }

    #endregion

    #region "METHODS"

    public override string ToString()
    {
        return string.Format("({0}){1}-{2}", Areacode, Prefix, Suffix);
    }

    #endregion
}

One Very Important Note

I’ve mentioned it already, but please note that in an effort to make these lean, I have not really added any validation to the entities. This is most certainly something you will need to add, perhaps in the entity itself, a business layer, or wherever you see fit to add this validation. You will certainly get unexpected results without validating your entities. Also, it may be appropriate to throw exceptions when attempting to retrieve properties that are dependent on another property that is not filled out. Here, I’ve simply returned an empty string in most cases, so it depends on your preferential usage.

As always, please feel free to add any comments about entities, best practices, code standards, structure, pro’s and con’s of logic within entities, and any other goodies you would like to contribute. Good luck and happy coding!

One thought on “Common Reusable Business Entities Part 3

Leave a comment