Skip to content

FormatterService Matching logic

JP edited this page Aug 10, 2020 · 3 revisions

This page should give you a clue how the default MorestachioFormatterService(MFS) matches the given Arguments to a Formatter. If the pattern does not match your need you can always create a new on your own by implementing the IMorestachioFormatterService or extend one of its methods (which are all virtual).

First to start with is the Task<object> CallMostMatchingFormatter( [NotNull]Type type, [NotNull]KeyValuePair<string, object>[] values, object sourceValue, [CanBeNull]string name) method that will be called from the CallFormatterDocumentItem. Worth noting is that Type type will always be the type that sourceValue is of.

When a Formatter should be called the MFS will loop through all Formatters and first checks the name for equality.

if the name matches the Input type will be compared.

  1. If the types are nether equal nor assignable from each other:
  2. MFS will try to obtain a ValueConverter to transform the given value to the exact value that the Formatter specifies. If that fails too:
  3. MFS will check if the Formatter has specified a ValueConverter for this specific Argument. If that fails too:
  4. MFS will obtain a list of generic type Arguments of that function and checks if the SourceValue of the Formatter is an generic type Argument. If that fails too the Formatter is skiped.

if any of the above is true:

  • MFS will check if the list of required Arguments are match in length

A required Argument is an Argument that is not c# Optional (does not define a default value nor has the [Optional] attribute) and does not fit into the "RestObject" pattern. The Rest Argument is an Argument at the end of an Formatter that is of type object[] and has the [RestParameter] Attribute)

  • MFS will then loop through all declared Arguments that are no Rest Argument.
  1. If the Argument is marked to be the SourceObject the supplied value from the original path is taken
  2. If the Argument is not marked to be the SourceObject MFS will try to match the name of the Argument with any supplied ArgumentName from the template

It is possible to annotate the name of the Argument you are supplying from the template by using {{Data.Format([Name]"value")}} That will ether match the real c# Parameter name or (if annotated with) match with the value from the [FormatterArgumentName("Name")].

  1. If no match by name was found, MFS will try to match the value to the Argument by its index.
  2. If no value for the current argument from the template was found, MFS will check if the Argument is optional. Else Skip.
  3. MFS will check if the argument is an Generic Argument. If not goto X

Hint Generic types are only limited supported by MFS current Implementation. Only Types with a generic type are supported

this is mainly for the support of list interfaces that contain a single generic argument like IEnumerable<T>

Generic Constrains are not supported (will throw an exception and stop the execution)

Multiple Generic Arguments are not supported (will never match)

Direct Generic arguments such as public static void Formatter<T>(T value) are not supported

  1. MFS will check if the the amount of generic arguments of the supplied value from the template matches those of the formatter argument. If not MFS will check if the supplied value is an array and will take the element type as generic argument instead (for IEnumerable from int[] support)

WIP