Creatio development guide
PDF
This documentation is valid for Creatio version 7.16.0. We recommend using the newest version of Creatio documentation.

Creating replacement classes in packages

Glossary Item Box

Specifics of creating replacement classes

Working with replacement classes has the following specifics:

  1. You must set a dependency on the replaceable class for a replacement class.
  2. Developing replaceable and replacement classes must follow C# inheritance principles. In the hierarchy, the replaceable class is a parent, and the replacement class a descendant.
  3. All properties and methods of a class to be replaced in other schemas must be virtual. In the replacement classes, these properties and methods are overloaded with the “override” keyword.
  4. When instantiating replacement classes, comply with the general rules for creating and applying constructors.
  5. Before the compilation, all properties and methods declared in the replacement class and not explicitly declared as virtual in the replaceable class will not be available. Binding and injection of type dependencies are implemented by the Ninject open-source framework for dependency injection only during execution.
  6. When creating replaceable classes with parameterized constructors, make sure to comply with the rules for naming data types of argument instances that are passed as parameters to the Get<T> method.

Case description

Create a replaceable class and configuration service in a custom package. Create a replacement class in another custom package. Demonstrate the operation of the configuration service with and without class replacement.

Learn more about developing replacement classes in the “Replacement class object factory” article.

Source code

You can download the packages with case implementation using the following link.

Case implementation algorithm

1. Implement a replaceable class

Go to the [Advanced settings] section -> [Configuration] -> Custom package -> the [Schemas] tab. Click [Add] -> [Source code]. Learn more about creating a schema of the [Source Code] type in the “Creating the [Source code] schema” article.

Specify the following parameters for the created object schema (Fig. 1):

  • [Title] – “OriginalClassSourceSchema”.
  • [Name] – "UsrOriginalClassSourceSchema".

Fig. 1. – Setting up the [Source Code] type object schema

Implement a replaceable class OriginalClass that contains the GetAmount(int, int) method for adding two values passed as parameters. The complete source code of the module is available below:

namespace Terrasoft.Configuration
{
    public class OriginalClass
    {
        // The GetAmount() method is virtual. It can be reloaded by descendants and is
        // implemented.
        public virtual int GetAmount(int originalValue1, int originalValue2)
        {
            return originalValue1 + originalValue2;
        }
    }
}

After making changes, save and publish the schema.

2. Create a configuration service

To demonstrate the operation of the GetAmount(int, int) method of the OriginalClass replaceable class, create a configuration service. Learn more about creating a custom configuration service in the “Configuration service development” article.

Go to the [Advanced settings] section -> [Configuration] -> Custom package -> the [Schemas] tab. Click [Add] -> [Source code]. Learn more about creating a schema of the [Source Code] type in the “Creating the [Source code] schema” article.

Specify the following parameters for the created object schema (Fig. 2):

  • [Title] – “AmountService”.
  • [Name] – "UsrAmountService".

Fig. 2. – Setting up the [Source Code] type object schema

Implement a replacement class AmountService that contains the GetAmount(int, int), method for adding two values passed as parameters. The full source code with the implementation of the service is available below.

namespace Terrasoft.Configuration
{
    using System.ServiceModel;
    using System.ServiceModel.Activation;
    using System.ServiceModel.Web;
    using Terrasoft.Core;
    using Terrasoft.Web.Common;

    [ServiceContract]
    [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Required)]
    public class AmountService : BaseService
    {

        [OperationContract]
        [WebGet(RequestFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Wrapped, ResponseFormat = WebMessageFormat.Json)]
        public string GetAmount(int value1, int value2) {
            /*
            // Instantiating the original class using the class factory.
            var originalObject = Terrasoft.Core.Factories.ClassFactory.Get<OriginalClass>();

            // Getting the result value of the GetAmount() method. Values from page fields are passed as the parameters.
            int result = originalObject.GetAmount(value1, value2);

            // Returning the result
            return string.Format("The result value, retrieved after calling the replacement class method : {0}", result.ToString());
            */

            /*
            // Instantiating the replacement class using the replacement class factory.
            // The factory is given an instance of the constructor class argument as an input parameter.
            var substObject = Terrasoft.Core.Factories.ClassFactory.Get<OriginalClass>(new Terrasoft.Core.Factories.ConstructorArgument("rateValue", 2));

            // Getting the result value of the GetAmount() method. Values from page fields are passed as the parameters.
            int result = substObject.GetAmount(value1, value2);

            // Displaying the result on the page
            return string.Format("The result value, retrieved after calling the replaceable class method: {0}", result.ToString());
            */

            // Instantiating the replacement class using new() operator.
            var substObjectByNew = new OriginalClass();

            // Instantiating the replacement class using the replacement class factory.
            var substObjectByFactory = Terrasoft.Core.Factories.ClassFactory.Get<OriginalClass>(new Terrasoft.Core.Factories.ConstructorArgument("rateValue", 2));

            // Getting the result value of the GetAmount() method. The OriginalClass method will be called without replacement.
            int resultByNew = substObjectByNew.GetAmount(value1, value2);

            // Getting the result value of the GetAmount() method. The SubstituteClass method will be called. SubstituteClass is a replacement for OriginalClass.
            int resultByFactory = substObjectByFactory.GetAmount(value1, value2);

            // Displaying the result on the page
            return string.Format("Result without class replacement: {0}; Result with class replacement: {1}", resultByNew.ToString(), resultByFactory.ToString());
        }
    }
}

After making changes, save and publish the schema.

3. Implement a replacement class

Add the custom package with the replaceable class as a dependency for the custom package with the replacement class.

Go to the [Advanced settings] section -> [Configuration] -> Custom package -> the [Schemas] tab. Click [Add] -> [Source code]. Learn more about creating a schema of the [Source Code] type in the “Creating the [Source code] schema” article.

Specify the following parameters for the created object schema (Fig. 8):

  • [Title] – “SubstituteClassSourceSchema”.
  • [Name] – "UsrSubstituteClassSourceSchema".

Fig. 3. – Setting up the [Source Code] type object schema

Implement a replacement class SubstituteClass that contains the GetAmount(int, int) method. The overloaded method adds the two values passed as parameters and multiplies the resulting value by the value passed in the Rate property. The initialization of the Rate property will be performed in the constructor of the replacement class. The complete source code of the module is available below:

namespace Terrasoft.Configuration
{
    [Terrasoft.Core.Factories.Override]
    public class SubstituteClass : OriginalClass
    {
        // Rate. The value of the property is assigned in the class.
        public int Rate { get; private set; }
        
        // The constructor runs a preliminary initialization of the Rate property with a passed rate value.
        public SubstituteClass(int rateValue)
        {
            Rate = rateValue;
        }

        // Replacnig a parent class with a custom implementation.
        public override int GetAmount(int substValue1, int substValue2)
        {
            return (substValue1 + substValue2) * Rate;
        }
    }
}

As a result, the new configuration service AmountService with a GetAmount endpoint will be available in the Creatio application. When accessing the endpoint of the service, such as using a browser, pass values value1 and value2.

To demonstrate the operation of the configuration service with and without class replacement, insert the following string in the address bar:

https://mycreatio.com/0/rest/AmountService/GetAmount?value1=25&value2=125

The result of the GetAmount(int, int) method is displayed below.

{"GetAmountResult":"Result without class replacement: 150; Result with class replacement: 300"}
© Creatio 2002-2020.

Did you find this information useful?

How can we improve it?