ObjectImplAttribute Class |
Namespace: PDTec.IceNet.Core.Model.Implementation
public class ObjectImplAttribute : Attribute
The ObjectImplAttribute type exposes the following members.
Name | Description | |
---|---|---|
ObjectImplAttribute |
Creates an attribute instance. Used internally.
|
Name | Description | |
---|---|---|
Interface |
Gets or sets the CLR type of the Business Object interface that
should be tied to the ice.NET object type identified by the
ObjTypeName property.
| |
ObjTypeName |
Gets or sets the ice.NET object type name. Use the fully qualified
object type name, not the display name.
| |
TypeId | When implemented in a derived class, gets a unique identifier for this Attribute. (Inherited from Attribute.) |
Name | Description | |
---|---|---|
Equals | Returns a value that indicates whether this instance is equal to a specified object. (Inherited from Attribute.) | |
Finalize | Allows an object to try to free resources and perform other cleanup operations before it is reclaimed by garbage collection. (Inherited from Object.) | |
GetHashCode | Returns the hash code for this instance. (Inherited from Attribute.) | |
GetType | Gets the Type of the current instance. (Inherited from Object.) | |
IsDefaultAttribute | When overridden in a derived class, indicates whether the value of this instance is the default value for the derived class. (Inherited from Attribute.) | |
Match | When overridden in a derived class, returns a value that indicates whether this instance equals a specified object. (Inherited from Attribute.) | |
MemberwiseClone | Creates a shallow copy of the current Object. (Inherited from Object.) | |
ToString | Returns a string that represents the current object. (Inherited from Object.) |
This example explains how to implement ice.NET Business Objects (BOs). The data model that is used for this example is part of the ice.NET Ice Car Rental turorial and can be found in the PDTec.ICR model package.
The example consists of multiple parts:
The first part of the example shows a BO interface definition. It is a normal C# interface that derives from the IObject interface. It can contain arbitrary methods and properties .
The following code is stored in the file IVehicle.cs:
using System; using PDTec.IceNet.Core.Model; namespace PDTec.ICR.BusinessLogic.BusinessObjects { public interface IVehicle : IObject { double CurrentMileage { get; set; } double CalculatePrice(DateTime pFromDate, DateTime pToDate); } }
The interface IVehicle is implemented in the next code example. To implement a BO interface a class is required that is derived from PDTec.IceNet.Sdk.Implementation.CObjectImplBase" and implements the BO interface.
The following code is stored in the file CVehicleImpl.cs:
using System; using System.Collections; using PDTec.IceNet.Core.Model; using PDTec.IceNet.Core.Model.Implementation; using PDTec.IceNet.Sdk.Implementation; using PDTec.ICR.BusinessLogic.BusinessObjects; namespace PDTec.ICR.BusinessLogic.BusinessObjects.Implementation { public class CVehicleImpl : CObjectImplBase, IVehicle { public CVehicleImpl(IRepository pRepository, IObjectImpl pObject) : base(pRepository, pObject) { } public double CurrentMileage { get { return (double)GetAttrValue("PDTec.ICR.Vehicle", "CurrentMileage"); } set { SetAttrValue("PDTec.ICR.Vehicle", "CurrentMileage", value); } } private IModel Model { get { IRelationship pRelationship = GetSingleRelationship("PDTec.ICR.VehicleModel", RelDirection.Forward); IModel pResult = pRelationship.GetObject(Direction.To).Cast<IModel>(); return pResult; } } public double CalculatePrice(DateTime pFromDate, DateTime pToDate) { TimeSpan pTimeSpan = pToDate - pFromDate; double price = pTimeSpan.Days * DailyRate - Model.CalculateRebate(this); return price; } } }
To associate the BO implementation with a modeled object type a BO factory is required. This factory class is decorated with a code attributes of type ObjectImplAttribute and implements IObjectImplFactory.
The property ObjTypeName defines the association with the ice.NET object type. All object instances of this type (or its subtypes) provide the BO methods declated in the BO interface.
The following code is stored in the file CVehicleImplFactory.cs:
using PDTec.IceNet.Core.Model; using PDTec.IceNet.Core.Model.Implementation; namespace PDTec.ICR.BusinessLogic.BusinessObjects.Implementation { [ObjectImpl(ObjTypeName="PDTec.ICR.Vehicle", Interface=typeof(IVehicle))] public class CVehicleImplFactory : IObjectImplFactory { public IObject CreateObject(IRepository pRepository, IObjectImpl pBaseImpl) { return new CVehicleImpl(pRepository, pBaseImpl); } } }
The BO factory provides the connection between interface, implementation and data model. In order to be used in an application, the containing .NET assembly must be registered with the .NET platform. The easies way to do this is to add a <implementationAssembly> tag that contains the assembly name into the application's configuration file as shown in the follwing example.
If the BO interface, the implementation and the factory class are distributed over multiple assemblies, the assembly containing the factory class must be registered in the configuration file.
The following code is part of a .NET configuration file (e.g. web.config):
<?xml version="1.0"?> <configuration> <configSections> <section name="ice.net" type="PDTec.IceNet.Sdk.ConfigSectionHandler,PDTec.IceNet.Sdk"/> </configSections> <ice.net> <database service="SQLServer" connectionString="server=(local)\SQLEXPRESS;trusted_connection=yes;database=icr" encrypted="false"/> <businessObjects> <implementationAssembly assemblyName="PDTec.ICR.BusinessLogic"/> </businessObjects> <!-- ... --> </ice.net> <!-- ... --> </configuration>
The following code shows how to use the BO methods:
IVehicle pVehicle = Repository.Get<IVehicle>(Request["vid"]); double price = pVehicle.CalculatePrice(DateTime.UtcNow, DateTime.UtcNow.AddDays(2.0));
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 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 CastBaseT(IObjType) 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; } } }