The implementation of the final Mapping Rule in the Target Engine and the Bag in the Source Engine is very similar to what you want through in the previous exercise. There are only a few minor differences

  • The Mapping Rule GetCardStatus uses a Valueset and a Constant, so you will see how to use other items created in the generated Engine code
  • The Bag method StringHandling.TruncateString of course exists in a Bag with other methods and possibly properties


Below we are going to focus on these differences as the rest is really the same as what you have just done for the Validation Rule String1ProvidedNotString2. 


Implement Mapping Rule GetCardStatus

  • In Visual Studio, create the new Rule under the folder Workshop.TargetEngine\MappingRule
  • Name the new file GetCardStatus.cs
  • Cleanup the namespace by deleting the trailing MappingRule
  • Replace the class declaration class GetCardStatus with the class declaration partial class MappingRules
  • Get the method signature from Intellisense by inserting a new line in the MappingRules class, type override and a space and select the GetCardStatus method from the Intellisense list

Now provide the implementation as specified in Studio and save the new implementation:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MigFx.Engine.Project.Target
{
  partial class MappingRules
  {
    public override Decimal GetCardStatus(FlagHandler flag, string CardStatus, DateTime? CardAtiveDate, DateTime? CardInactiveDate)
    {
      var row = Valueset.CardStatus
        .Where(r => r.CardStatus == CardStatus)
        .Select(r => new { r.CardStatusId })
        .FirstOrDefault();

      if (row != null)
      {
        return row.CardStatusId;
      }
      else
      {
        if (CardActiveDate <= SystemConstant.FirstBankDay && CardInactiveDate.GetValueOrDefault(SystemConstant.FirstBankDay) >= SystemConstant.FirstBankDay)
        {
          flag(1); // Card in use
        }
        else
        {
          flag(2); // Card not in use
        }

        return 0;
      }
    }
  }
}


Just a few interesting things to point out in this implementation

  • In line 13 above the rule is looking up a row in the Valueset CardStatus. Notice how easy this is due to the fact that the Engine code generator generated a property Valueset available to you - in turn with a queryable property for each Valuset defined in Studio. The syntax of the Language Integrated Query syntax in c# makes the lookup easy to construct and indeed easy to read
  • In Line 24 above the rule is using the Constant FirstBankDay. Again the Engine code generator has facilitated this by providing a property SystemConstants for you with all the Constants from Studio

Import to Studio

  • Open and checkout the Rule in Studio
  • Select the Code tab
  • Click the Import button. The File dialog should already point to the correct file
  • Check Implemented
  • Save and check in

Implement Bag method StringHandling.TruncateString

Now on to the last manual implementation to do. This time you will be adding a method to the StringHandling Bag in the Workshop Source Engine class library project in Visual Studio.


First open the the Bag located in Workshop.SourceEngineCustom\Bag\StringHandling.cs. Notice that the Bag methods already implemented have been placed in collapsible #regions for readability.


Provide the implementation of the method TruncateString as a #region:

 

    #region TruncateString 

    public override String TruncateString(TruncateStringFlagHandler flag, string InputString, Decimal? Length)
    {
      var inputString = (InputString ?? string.Empty).Trim();
      var length = (int)Length.GetValueOrDefault(int.MaxValue);

      if (inputString.Length <= length)
      {
        // Truncate not nessesary
        return inputString;
      }
      else      
      {
        // Truncate
        var truncated = inputString.Substring(0, length);

        flag(1, truncated);

        return truncated;
      }
    }

    #endregion


A few remarks to the implementation above

  • Since the method must provide a Flag Parameter when raising a flag, the Engine code generator has created a special FlagHandler delegate dedicated to this method. This TruncateStringFlagHandler is passed as the first parameter to the method in line 3 above
  • When the method raises the flag in line 13 it can pass the truncated string in addition to the flag number
  • At this point, when implementing a rule, there is really no guarantee, that the generated engine was able to find values for all the parameters - some of them may be null. As is done in this implementation in line 5 above, it is always prudent to guard against null values in the parameters   

When satisfied with your implementation import the implementation into Studio, mark the Bag implemented and remember to Check in.



Build your code

Before you finish this exercise, you should build your code and correct any compilation errors before proceeding. You can build the code by right-clicking either Workshop.SourceEngineCustom or Workshop.TargetEngine and select Build in the context menu.


What happened here?

In this and the previous exercise you have implemented all the manual Rules and Bag methods you have added to the Workshop Source- and Target Maps to handle the migration of the new Card Business Object.


While objective has not been to teach you c# (indeed a large subject) we hope you nevertheless have a good sense of how you easily can implement the manual rules specified in Studio and how your manual implementations integrates with the code created by the Engine code generator.


The Engine code generator gives access to all the items created in in Studio. You can

  • Use the values of all Constants
  • Query all Valuesets
  • Call other Rules and Bag metods
  • Set properties on Bags
  • Working in the Target Engine, you can 
    • Access the data received from the Source Engine for the entire root Business Object processing
    • Access the data produced (so far) by the Target Engine for the entire root Business Object processing
    • If a Relationship is defined in the current Business Object to another, you can access the same data from the other Business Object through this relationship
    • Use generated classes for each structure in the Target System metadata to inject target rows into the migration stream

Indeed, when implementing manual Rules and Bags you have the entire power of .NET at your disposal. There is not stopping you from calling out of your manual Rules and into your own proprietary functionality. 


This conclude this section of the exercise. You now have your two engine completed with the Card Business Object, all ready to rock and roll. In the next section you will get your engines deployed and setup in the runtime environment and ready to start executing.