Business Objects Inheritance Example

The following example is based on the PDTec.ICR tutorial model.

This example explains how to reimplement a BO interface for a subtype and make use of the base (supertype) implementation.

The example consists of multiple parts:

  • The BO interface definition.
  • A BO implementation for the base object type.
  • A BO implementation for a subtype.

The first part of the example shows the BO interface definition. It is designed for calcuating the speed of objects. It can be connected with object types such as PDTec.ICR.Model that describes vehicle models and its subtypes.

The following code is stored in the file IObjectInMotion.cs:

using PDTec.IceNet.Core.Model;

namespace PDTec.ICR.BusinessLogic.BusinessObjects
{
    public interface IObjectInMotion : IObject
    {
        double CalculateSpeed(int numberOfPassengers);
    }
}       

The interface IObjectInMotion is implemented for the root type of the PDTec.ICR.Model hierarchy. The implementation class CModelInMotionImpl contains the BO factory as an inner class. This is not necessary but avoids having to maintain an extra source file for the factory class.

We assume that object types of PDTec.ICR.Model provide an BO interface IModel that will be used in the implementation of IObjectInMotion.

The following code is stored in the file CModelInMotionImpl.cs:

using PDTec.IceNet.Sdk.Implementation;
using PDTec.IceNet.Core.Model;
using PDTec.IceNet.Core.Model.Implementation;

namespace PDTec.ICR.BusinessLogic.BusinessObjects.Implementation
{
    public class CModelInMotionImpl : CObjectImplBase, IObjectInMotion
    {
        [ObjectImpl(ObjTypeName="PDTec.ICR.Model", Interface=typeof(IObjectInMotion))]
        public class CImplFactory : IObjectImplFactory
        {
           public IObject CreateObject(IRepository pRepository, IObjectImpl pBaseImpl)
           {
               return new CModelInMotionImpl(pRepository, pBaseImpl);
           }
        }

        //------------------
        
        public CModelInMotionImpl(IRepository pRepository, IObjectImpl pObject) :
            base(pRepository, pObject)
        {
        }

        public double CalculateSpeed(int numberOfPassengers)
        {
            if (numberOfPassengers < 1)
            {
                throw new ArgumentException("numberOfPassengers");
            }

            return Cast<IModel>().EnginePower / (double)numberOfPassengers;
        }
    }
}

The interface IObjectInMotion is now reimplemented for the subtype PDTec.ICR.SportsCar. This type is modeled as a subtype of PDTec.ICR.Car which is a subtype of the hiearchy root type PDTec.ICR.Model.

The reimplementation makes use of the base implementation by calling the generic IObjectImpl.CastBase{T} method.

The following code is stored in the file CSportsCarInMotionImpl.cs:

using PDTec.IceNet.Sdk.Implementation;
using PDTec.IceNet.Core.Model;
using PDTec.IceNet.Core.Model.Implementation;

namespace PDTec.ICR.BusinessLogic.BusinessObjects.Implementation
{
    public class CSportsCarInMotionImpl : CObjectImplBase, IObjectInMotion
    {
        [ObjectImpl(ObjTypeName="PDTec.ICR.SportsCar", Interface=typeof(IObjectInMotion))]
        public class CImplFactory : IObjectImplFactory
        {
           public IObject CreateObject(IRepository pRepository, IObjectImpl pBaseImpl)
           {
               return new CSportsCarInMotionImpl(pRepository, pBaseImpl);
           }
        }

        //------------------

        public CSportsCarInMotionImpl(IRepository pRepository, IObjectImpl pObject) :
            base(pRepository, pObject)
        {
        }

        public double CalculateSpeed(int numberOfPassengers)
        {
            IObjType pBaseType = Repository.GetObjTypeByName(Constants.ObjType.Car);
            
            return 0.5 * (CastBase<IObjectInMotion>(pBaseType)).CalculateSpeed(numberOfPassengers)) +
                   0.5 * Cast<ISportsCar>().MaxSpeed;
        }
    }
}