![]() | Custom ValueModifiers |
This chapter deals with self-created ValueModifyers.
Custom ValueModifiers you will rarely need, because Vishnu already provides
ValueModifiers for the standard result types Boolean,
all Integer-types, DateTime and
String with standard C#-formatting.
What ValueModifiers actually are and how they are used is described in detail on
Vishnu actors
in ValueModifier.
Let's assume that you can no longer get by with the Vishnu-ValueModifiers and need to implement extended logic or handle a special result type. This is exactly what custom ValueModifiers are designed for.
In the following example, the corresponding moon phase is to be displayed for a given date. The internal result type is, as you can see below, simply Int32, but the conversion of the date into the value of a moon phase requires its own logic.
![]() |
---|
The following example also shows an application for Custom Views. Thanks also to https://www.freeimages.com/illustrations/vector/moonphase. |
This is what the demo job looks like for your own ValueModifier in operation:
A date can be entered (or selected) via the DateInput dialog, which is displayed in the Moon Phase node as an image of the moon phase that matches the date.
This is the JobDescription.xml for the demo job for your own ValueModifier:
<?xml version="1.0" encoding="utf-8"?> <JobDescription> <LogicalName>CheckUserValueModifier</LogicalName> <LogicalExpression> DateInput AND Moon phase </LogicalExpression> <Checkers type="array"> <Checker> <LogicalName>DateInput</LogicalName> <PhysicalPath>WPFDateDialog.dll</PhysicalPath> </Checker> </Checkers> <ValueModifiers> <ValueModifier> <LogicalName>Moon phase</LogicalName> <UserControlPath>Plugin\SingleNodeUserControl_CheckMoonPhase.dll</UserControlPath> <Reference>DateInput</Reference> <PhysicalPath>Plugin\DateToMoonage.dll</PhysicalPath> <Type>Object</Type> </ValueModifier> </ValueModifiers> </JobDescription>
As you can see, the instruction <PhysicalPath>Plugin\DateToMoonage.dll</PhysicalPath>
refers to your own UserValueModifier.
The type is generally set to Object for Vishnu. The UserValueModifier and the UserView
SingleNodeUserControl_CheckMoonPhase.dll are then responsible for the correct handling of the actual result type.
The UserValueModifier DateToMoonage.dll is in turn responsible for the correct handling of the result of the node DateInput, which is referred to with the instruction <Reference>DateInput</Reference>.
The DateToMoonAge class must implement the IValueModifier interface, as shown in the following code snippet.
... /// <summary> /// Converts a passed date into the corresponding moon age in days. /// </summary> /// <remarks> /// File: DateToMoonAge.cs /// Author: Erik Nagel, NetEti /// Many thanks to Mostafa Kaisoun for his calculation logic /// https://www.codeproject.com/script/Membership/View.aspx?mid=1961229 /// /// 04.04.2020 Erik Nagel: created /// </remarks> public class DateToMoonAge : IValueModifier { /// <summary> /// Converts a passed date into the corresponding moon age in days. /// </summary> /// <param name="toConvert">Date as DateTime.</param> /// <returns>Moon age in days.</returns> public object ModifyValue(object toConvert) { if (toConvert is DateTime) { if (toConvert != zero) { DateTime inDateTime = (DateTime)toConvert; return new DateToMoonAge_ReturnObject(this.MoonAge(inDateTime.Day, inDateTime.Month, inDateTime.Year)); } else { return toConvert; } } else { throw new ArgumentException(String.Format("{0}: cannot convert {1}, DateTime is expected", this.GetType().Name, toConvert.ToString())); } } ... private int MoonAge(int d, int m, int y) { ... } ... } ...
![]() |
---|
At this point, many thanks again to Mostafa Kaisoun for his calculation logic (https://www.codeproject.com/script/Membership/View.aspx?mid=1961229). How the calculation is carried out in detail is not important here, the only decisive factor is that it produces a result of type int (corresponds to Int32). |
The class DateToMoonAge returns an object of type DateToMoonAge_ReturnObject. The following code snippet shows excerpts from the corresponding class.
... /// <summary> /// ReturnObject for the result of the DateToMoonAge ValueModifier. /// </summary> /// <remarks> /// Author: Erik Nagel, NetEti /// /// 04.04.2020 Erik Nagel: created /// </remarks> [DataContract] //[Serialisable()] public class DateToMoonAge_ReturnObject { /// <summary> /// Moon age in days. /// </summary> [DataMember] public int MoonAge { get; set; } ... /// <summary> /// Constructor - accepts a string value for the DefaultResultProperty. /// </summary> /// <param name="resultProperty">Int value for the MoonAgeProperty</param> public DateToMoonAge_ReturnObject(int resultProperty) { this.MoonAge = resultProperty; } // Serialisation and de-serialisation routines follow ... } ...
This class is used to transport the result of DateToMoonAge.cs through the Vishnu-processing (as an anonymous object). SingleNodeUserControl_CheckMoonPhase.dll then resolves the object, which is anonymous for Vishnu, back to DateToMoonAge_ReturnObject. In order for this to work, routines for serializing and de-serializing the data to be transported (here the property DateToMoonAge_ReturnObject) must be implemented in DateToMoonAge_ReturnObject.
Serialisation and de-serialisation are always the same in principle and have already been described in detail in the chapter Custom Views in the subitem Serialisation. Please refer to this if necessary.
![]() |
---|
All code extracts are reduced to the parts necessary for the explanation. If you are interested in further details, you can consult the original sources at any time. |