Skip to content

Argument aliases

Giuseppe Cramarossa edited this page Dec 15, 2023 · 2 revisions

InterAppConnector provides the possibility to change the name of an argument or define different names for a specific argument by using argument aliases. In this section you will see

  • what is an alias and how it works
  • how to use this attribute in properties
  • an example that uses this attribute

If you don't know what is an argument and how to define it, it is strongly suggested that you see the arguments overview page.

Alias definition and limitations

In the previous lessons, you have seen how to declare arguments in a command and you have learned that the name of the property is the name of the argument.

It is possible to change the name of the arguments or define different aliases for a specific property. This is especially useful in code obfuscation or in the case you want to use a different name for your argument. When you use an alias for an argument, the library will use the arguments defined through the alias attribute and not the property name. This means that the property name won't be recognized as an argument, but only its aliases.

In order to define an alias, you need to add the Alias attribute to the property.

For instance, assuming that you have created a property named Username and you want to expose the property as an argument with a different name (for example user), you can write this piece of code in your argument definition

[Alias("user")]
public string Name {get; set;}

When you create a command, the library will check all the public properties defined for that command and its respective attributes and behaves as described below:

  • if the property has some alias attributes, the library will use the aliases as arguments
  • if the property has no aliases, the library will use the property name as argument

The use of this alias is not mandatory. You can define more than one alias for a property. However, there are some limitations when you use this attribute:

  • alias names should contain only alphanumerical characters and hyphens. If you use some characters not allowed, a null value or an empty string, an ArgumentException exception will be raised. Some examples of allowed alises are:

    • 2fa
    • -expose (in this case the argument to use will become --expose)
    • force-delete

    Some examples of aliases not allowed are:

    • ali@s
    • alias with space
    • !important
    • a null string
    • an empty string (or its relative constant such as String.Empty)
  • you cannot use the same alias for more than one property in the same argument list. If you try to do this a DuplicateObjectException exception will be raised

Aliases are case insensitive. This means for example that user and User is the same object and hence it cannot be used in more than one property. If you try to do this a DuplicateObjectException exception will be raised

Example

In this example, you are creating a simple user management application that has two commands

  • CreateUserCommand
  • DeleteUserCommand

These commands have two arguments:

  • usercode : contains the user code. This argument is mandatory for both commands
  • name : contains the user name. This argument is mandatory in user creation and mandatory in user deletion.

For this example you are using Visual Studio 2022 and you are creating:

  • A project library that contains the commands and a file containing the arguments necessary to run the application
  • A console application that will be used to call the command via cli

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. Open Visual Studio, create a blank solution and name it UserManager. Choose the language version (.NET 6 or above) and choose a location for your solution (for example C:\SampleProjects)

  2. Create a new library project and call it UserManager.Library. Then follow the steps below to complete the class library

    1. Add the InterAppConnector library as project reference

    2. Add a file to the project and call it UserManagerDataModel.cs

    3. Replace the content of UserManagerDataModel.cs with the code below

      namespace UserManager.Library
      {
          public class UserManagerDataModel
          {
              public string UserCode { get; set; } = string.Empty;
              public string FileLocation { get; set; } = string.Empty;
              public string Name { get; set; }
          }
      }
    4. Rename Class1.cs to CreateUserCommand.cs and create a new file called DeleteUserCommand.cs. Change the visibility in the classes from internal to public

    5. Replace the content of UserManagerDataModel.cs with the code below

      using InterAppConnector.Attributes;
      
      namespace UserManager.Library
      {
          public class UserManagerDataModel
          {
              public string UserCode { get; set; } = string.Empty;
              public string FileLocation { get; set; } = string.Empty;
              
              [MandatoryForCommand(typeof(CreateUserCommand))]
              [Alias("user")]
              public string Name { get; set; }
          }
      }
    6. Replace the content of CreateUserCommand.cs with the code below

      using InterAppConnector;
      using InterAppConnector.Attributes;
      using InterAppConnector.Interfaces;
      using System.Text.RegularExpressions;
      
      namespace UserManager.Library
      {
          [Command("create", Description = "Create a user in a file")]
          public class CreateUserCommand : ICommand<UserManagerDataModel>
          {
              public string Main(UserManagerDataModel arguments)
              {
                  string message = "";
                  bool userAlreadyExists = false;
      
                  if (Regex.IsMatch(arguments.UserCode, @"^[a-z0-9]+$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(1000))
                      && Regex.IsMatch(arguments.Name, @"^[a-z ]+$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(1000)))
                  {
                      if (File.Exists(arguments.FileLocation))
                      {
                          List<string> userList = new List<string>(File.ReadLines(arguments.FileLocation));
                          int rowsFound = (from item in userList
                                          where item.ToLower().StartsWith(arguments.UserCode.ToLower() + ",")
                                          select item).Count();
      
                          if (rowsFound > 0)
                          {
                              userAlreadyExists = true;
                          }
                      }
      
                      if (userAlreadyExists)
                      {
                          message = CommandOutput.Warning("The user code already exists. No row was added");
                      }
                      else
                      {
                          File.AppendAllText(arguments.FileLocation, arguments.UserCode.Trim() + "," + arguments.Name + Environment.NewLine);
                          message = CommandOutput.Ok("The user was added to the list");
                      }
                  }
                  else
                  {
                      message = CommandOutput.Error("The user code or the name contains invalid characters.\nPossible causes:\n-user code contain other characters than letter and numbers\n-name contains other characters other than letters and spaces");
                  }
      
                  return message;
              }
          }
      }
    7. Replace the content of DeleteUserCommand.cs with the code below

      using InterAppConnector;
      using InterAppConnector.Attributes;
      using InterAppConnector.Interfaces;
      using System.Text.RegularExpressions;
      
      namespace UserManager.Library
      {
          [Command("delete", Description = "Delete a user in a file")]
          public class DeleteUserCommand : ICommand<UserManagerDataModel>
          {
              public string Main(UserManagerDataModel arguments)
              {
                  string message = "";
      
                  if (Regex.IsMatch(arguments.UserCode, @"^[a-z0-9]+$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(1000)))
                  {
                      if (File.Exists(arguments.FileLocation))
                      {
                          string name = "";
                          bool isNameValid = true;
                          List<string> userList = new List<string>(File.ReadLines(arguments.FileLocation));
                          List<string> rowsFound = new List<string>();
      
                          if (!string.IsNullOrEmpty(arguments.Name))
                          {                    
                              if (Regex.IsMatch(arguments.Name, @"^[a-z ]+$", RegexOptions.IgnoreCase, TimeSpan.FromMilliseconds(1000)))
                              {
                                  name = arguments.Name;
                                  rowsFound = (from item in userList
                                              where item.ToLower() == arguments.UserCode.ToLower() + "," + name.ToLower()
                                              select item).ToList();
                              }
                              else
                              {
                                  isNameValid = false;
                              }
                          }
                          else
                          {
                              rowsFound = (from item in userList
                                          where item.ToLower().StartsWith(arguments.UserCode.ToLower() + ",")
                                          select item).ToList();
                          }
      
                          if (isNameValid)
                          {
                              
                              if (rowsFound.Count > 0)
                              {
                                  userList.Remove(rowsFound[0]);
                                  File.WriteAllLines(arguments.FileLocation, userList);
                                  message = CommandOutput.Ok("User deleted successfully");
                              }
                              else
                              {
                                  message = CommandOutput.Warning("The user does not exist. No rows was deleted");
                              }
                          }
                          else
                          {
                              message = CommandOutput.Error("The name contains invalid characters. Only letters and spaces are allowed");
                          }
      
                      }
                      else
                      {
                          message = CommandOutput.Error("The file does not exist");
                      }
                  }
                  else
                  {
                      message = CommandOutput.Error("The user code contains invalid characters. Only letters and numbers are allowed");
                  }
      
                  return message;
              }
          }
      }
  3. Create a new console application project and name it UserManager.CLI. Then follow the steps below to complete the console application:

    1. Add the InterAppConnector library as project reference

    2. Add the UserManager.Library project as project reference

    3. Replace the content of Program.cs with the code below (CommandManager and InterAppConnector are explained in detail in Integration with console applications page)

      using InterAppConnector;
      using UserManager.Library;
      
      namespace UserManager.CLI
      {
          public class Program
          {
              static void Main(string[] args)
              {
                  CommandManager commandManager = new CommandManager();
                  commandManager.AddCommand<CreateUserCommand, UserManagerDataModel>()
                      .AddCommand<DeleteUserCommand, UserManagerDataModel>();
      
                  InterAppCommunication interAppCommunication = new InterAppCommunication(commandManager);
                  interAppCommunication.ExecuteAsInteractiveCLI(args);
              }
          }
      }
  4. Build the solution (you can leave the debug mode if you want)

  5. Open the Command Prompt and go to the location of the executable. For instance, if you have placed your solution in C:\SampleProjects you can go to the executable by typing the above command

    cd C:\SampleProjects\UserManager\UserManager.CLI\bin\Debug\net6.0
  6. Type the executable name with the extension (for instance UserManager.CLI.exe). You should see an output similar to the one below

    ----------------------------------------------------------------------------------
    
    UserManager.CLI 1.0.0.0
    
    ----------------------------------------------------------------------------------
    
    Available actions:
    
    - create
    Create a user in a file
            -usercode (required) : No description provided
            -filelocation (required) : No description provided
            -user (required) : No description provided
    
    - delete
    Delete a user in a file
            -usercode (required) : No description provided
            -filelocation (required) : No description provided
            -user (optional) : No description provided

    As you can see there isn't an argument called name but there is its alias user. Moreover, user is mandatory for the create command and optional for the delete one. Ignore the argument description for the moment

  7. Try to use the orginal name of the property as argument. For instance, type create -usercode john -filelocation ".\users.csv" -name John. You should see this error

    [22/10/2023 17:31:27] ERROR (3) : Cannot execute the selected action because some mandatory parameters are missing. Missing parameters: user
    - create
    Create a user in a file
            -usercode (required) : No description provided
            -filelocation (required) : No description provided
            -user (required) : No description provided
  8. Create a new user and try to not define the name. For instance, type UserManager.CLI.exe create -usercode john -filelocation ".\users.csv". You should see this error

    [22/10/2023 17:19:45] ERROR (3) : Cannot execute the selected action because some mandatory parameters are missing. Missing parameters: name
    - create
    Create a user in a file
           -usercode (required) : No description provided
           -filelocation (required) : No description provided
           -user (required) : No description provided
  9. Now type all required parameters (for instance type UserManager.CLI.exe create -usercode john -filelocation ".\users.csv" -user John). You should see a success message like the message below

    [22/10/2023 17:31:27] SUCCESS (0) : The user was added to the list
  10. Now let's try to delete the user without using the optional parameter. Type UserManager.CLI.exe delete -usercode john -filelocation ".\users.csv" and press enter. You should see a message like the one below

    [22/10/2023 19:47:50] SUCCESS (0) : User deleted successfully