We will now create the Project object.

Create an Interface

Ingeniux recommends starting with an interface and defining the requirements for the object. In this example, create a new interface called “IProject”. Assign the following properties:

  • Title

  • Description

  • Related Assets

  • Start Date

  • Projected End Date

  • Actual End Date

  • Status

Title and Description are provided by the FolioItemBase base class as “Name” and “Description”. Related Assets can be just “Asset”.

Note

An Asset in Cartella is a collection of files with same meta data, not just one file. Four additional properties are required: StartDate, ProjectedEndDate, ActualEndDate, and CurrentStatus.

A project needs a list of contacts. Add a relations object to allow the manipulation of the relationship between this project and a list of users.

The interface will look like below. Add three using statements for Cartella.Interfaces, Cartella.Classes, and Cartella.Support for coding convenience.

Define an enum called ProjectStatus to limit the value of status choices.

Your code should look like this:

CopyC#
using System;
using Cartella.Classes;
using Cartella.Interfaces;


namespace Cartella.Interfaces
{
    public enum ProjectStatus
    {
        OnGoing,
        Completed,
        Cancelled
    }

    public interface IProject : IAssetFolioItem
    {
        DateTime StartDate { get; set; }
        DateTime ProjectedEndDate { get; set; }
        DateTime ActualEndDate { get; set; }
        ProjectStatus CurrentStatus { get; set; }

        ICartellaRelations<IProject, IUser> Contacts { get; }
    }
}

Create the "Project" Class

Next, Create a Project class and have it inherit AssetFolioItemBase and implement the newly defined interface IProject. Implementing both the abstract base class and interface gives this:

Important

In order for Cartella to find any custom object, the object must be in the namespace Cartella.Classes.

CopyC#
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Cartella.Classes;
using Cartella.Interfaces;
using Cartella.Support;

namespace Cartella.Classes
{
    public class Project : AssetFolioItemBase, IProject
    {
        public override Type[] AllowedChildrenTypes
        {
            get { throw new NotImplementedException(); }
        }

        public override IAsset Asset
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #region IProject Members

        public DateTime StartDate
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public DateTime ProjectedEndDate
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public DateTime ActualEndDate
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        public ICartellaRelations<IProject, IUser> Contacts
        {
            get { throw new NotImplementedException(); }
        }

        public ProjectStatus CurrentStatus
        {
            get
            {
                throw new NotImplementedException();
            }
            set
            {
                throw new NotImplementedException();
            }
        }

        #endregion
    }
}

Filling out our class

  1. Constructors

    Your new class must have two constructors, one with no parameters (no generic based construction) and one that accepts a list of fields (IFieldCollection) and its own manager as ICartellaObjectManager.

    CopyC#
    public Project()
            {
            }
    
            public Project(IFieldCollection fields, ICartellaObjectManager manager)
                : base(fields, manager)
            {
            }
  2. Implement the AllowedChildrenTypes property. Project does not require any children. Return the empty array of types:

    CopyC#
    public override Type[] AllowedChildrenTypes
            {
                get
                {
                    return new Type[] { };
                }
            }
  3. Implement the Asset property. This is a database field property. Protected methods getAsset and setAsset are provided. It will be an extended column. Use the string "EX_Asset" with the getAssest and setAsset methods.

    Important

    The “EX_” prefix is very important.

    Define a constant string to represent this name and implement the Asset property:

    CopyC#
    const string assetMemberName = "EX_Asset";
            public override IAsset Asset
            {
                get
                {
                    return base.getAsset(assetMemberName);
                }
                set
                {
                    base.setAsset(assetMemberName, value);
                }
            }
  4. Implement the date-related properties StartDate, ProjectedEndDate, and ActualEndDate. They are all extended columns in the database.

    CopyC#
    const string startDateMemberName = "EX_Z1StartDate";
            const string projectedEndDateMemberName = "EX_Z2ProjectedEndDate";
            const string actualEndDateMemberName = "EX_Z3ActualEndDate";
    
            public DateTime StartDate
            {
                get
                {
                    return base.getFieldValue<DateTime>(startDateMemberName);
                }
                set
                {
                    this[startDateMemberName] = value.ToShortDateString();
                }
            }
    
            public DateTime ProjectedEndDate
            {
                get
                {
                    return base.getFieldValue<DateTime>(projectedEndDateMemberName);
                }
                set
                {
                    this[projectedEndDateMemberName] = value.ToShortDateString();
                }
            }
    
            public DateTime ActualEndDate
            {
                get
                {
                    return base.getFieldValue<DateTime>(actualEndDateMemberName);
                }
                set
                {
                    this[actualEndDateMemberName] = value.ToShortDateString();
                }
            }
  5. Implement a CurrentStatus property that converts a string value to an enum:

    CopyC#
    const string statusMemberName = "EX_Z4Completed";
            public ProjectStatus CurrentStatus
            {
                get
                {
                    ProjectStatus status = ProjectStatus.OnGoing;
                    try
                    {
                        status = (ProjectStatus)Enum.Parse(typeof(ProjectStatus), this[statusMemberName]);
                    }
                    catch { }
                    return status;
                }
                set
                {
                    this[statusMemberName] = Enum.Format(typeof(ProjectStatus), value, "G");
                }
            }
  6. Implement theContact property. This property is relation-based and uses a separate mapping table. Actual implementation is simple. Define attribute-based procedure methods in the procedure classes.

    CopyC#
    public ICartellaRelations<IProject, IUser> Contacts
            {
                get
                {
                    return manager.CreateRelations<IProject, User, IUser>(this, false);
                }
            }