Skip to content

Argument setting rules

Giuseppe Cramarossa edited this page Oct 12, 2024 · 4 revisions

From version 0.4.0, you can define setting rules. In this page you will find information about argument definition rules. In particular, it contains:

  • what is a setting rule
  • generic setting rule
  • setting rule specific to an attribute
  • an example that shows how to use a setting rule

Prior to read this page, it is suggested to read the page that explains what is a rule in general

What is a definition rule

Argument setting rules are evaluated after the argument definition ones. At this point, it is known also the value inserted by the user.

This is the right place for validators and all rules where the value inserted by the user is necessary to take decisions

You can create two types of argument rules:

  • generic rules
  • specializeed rules

Generic rules

Generic rules are not associated to any attribute, and they are very useful if you want to define a generic rule for an object. You may need to define an argument that does not have any specific attribute, but you have to associate some specific tasks or add some functionalities. Generic rules helps to cover this case.

In order to define a generic rule, you have to use a class that implements the IArgumentSettingRule interface, as showed in the code below

public class GenericRule : IArgumentSettingRule
{
    public bool IsRuleEnabledInArgumentSetting(PropertyInfo property)
    {
        return true;
    }

    public bool IsRuleEnabledInArgumentSetting(FieldInfo field)
    {
        return true;
    }

    public ParameterDescriptor SetArgumentValueIfTypeDoesNotExist(object parentObject, PropertyInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }

    public ParameterDescriptor SetArgumentValueIfTypeDoesNotExist(object parentObject, FieldInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }

    public ParameterDescriptor SetArgumentValueIfTypeExists(object parentObject, PropertyInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }

    public ParameterDescriptor SetArgumentValueIfTypeExists(object parentObject, FieldInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }
}

In particular, you can see that there are three main methods that have two overloads (for a total of six methods)

  • IsRuleEnabledInArgumentSetting is executed always and define if the rule should be executed or not
  • SetArgumentValueIfTypeDoesNotExist is not executed in any case in generic rules. Probably they wll be removed in future versions
  • SetArgumentValueIfTypeExists is executed if the rule is enabled

The main difference between the overloads is that one method accept a property (the method with PropertyInfo) and the other accept a field (the method with FieldInfo)

Specialized rules

Specialized rules are associated to an attribute, and they are very useful if you want to define a behaviour for a rule that has a specific attribute.

Let's assume you have created an attribute called MyCustomAttribute and you want to define a rule. In order to define a specific rule, you have to use a class that implements the IArgumentSettingRule<ParameterType> interface, as showed in the code below

public class GenericRule : IArgumentSettingRule<MyCustomAttributeAttribute>
{
    public bool IsRuleEnabledInArgumentSetting(PropertyInfo property)
    {
        return true;
    }

    public bool IsRuleEnabledInArgumentSetting(FieldInfo field)
    {
        return true;
    }

    public ParameterDescriptor SetArgumentValueIfTypeDoesNotExist(object parentObject, PropertyInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }

    public ParameterDescriptor SetArgumentValueIfTypeDoesNotExist(object parentObject, FieldInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }

    public ParameterDescriptor SetArgumentValueIfTypeExists(object parentObject, PropertyInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }

    public ParameterDescriptor SetArgumentValueIfTypeExists(object parentObject, FieldInfo property, ParameterDescriptor argumentDescriptor, ParameterDescriptor userValueDescriptor)
    {
        return argumentDescriptor;
    }
}

In particular, you can see that there are three main methods that have two overloads (for a total of six methods)

  • IsRuleEnabledInArgumentSetting is executed always and define if the rule should be executed or not
  • SetArgumentValueIfTypeExists is executed if the type or the attribute exists and the rule is enabled
  • SetArgumentValueIfTypeDoesNotExist is executed only if the attribute or the type is not present and if the rule is enabled

The main difference between the overloads is that one method accept a property (the method with PropertyInfo) and the other accept a field (the method with FieldInfo)

Example

In this example, we will create a simple hello world definition rule that will print a message when an argument of a custom type is defined as argument of a command

We will create

  • the library that contains the rule and an example command
  • the console application

For this example it is assumed that you have learned what is a command and how to implement it

Follow these steps to complete this example:

  1. Clone the example repository available here
  2. Build and run the BasicArgumentSettingRule project available in folder rule
  3. If you execute the activityexample command, You can see something like the output below:
[04/01/2024 18:49:11] SUCCESS (0) : 2 elements in the list
 Maximum activity row number not set: Default value: 50

 Command start
  1. If you try to set a value to maxactivityrownumber (for example 30) you should see something like the output below
[04/01/2024 18:49:11] SUCCESS (0) : 2 elements in the list
 Maximum row number set: 30

 Command start