Model Validation
Overview
This is a tutorial on performing model validation using NDCLI. 
Develop a command line extension to output the model validation results to standard output when the command is executed from NDCLI.
- Implement the following validations:
 - Model validation
 - Feature validation
 - Configuration validation
 - Specify the following options to execute the command:
 - "--projectPath" or "-p": Specifies the path to the project file to validate. This option is required.
 - "--model" or "-m": Specify true to perform model validation.
 - "--feature" or "-f": Specify true to perform feature validation.
 - "--configuration" or "-c": Specify true to perform configuration validation. 
Command Example 
ndcli ModelValidate --projectPath "{project file storage path}\Advanced Driving System Software Development.nproj" --model true --feature true --configuration true
Overall Flow
- Preparing the Command Line Extension
 - Implementing Command Processing
 - Deploying to the Execution Environment
 - Executing the Command Line Extension
 
Public Sample
- The source code created as a result of this tutorial and the project files required to execute the commands are available on GitHub.
External link: Model Validation
 
Goal Image
- When you run the model validation command line extension from NDCLI, the following message is output. 
 
> ndcli ModelValidate --projectPath "{project file storage path}\Advanced Driving System Software Development.nproj" --model true --feature true --configuration true
NextDesign.ModelValidate
Project : {project file storage path}\Advanced Driving System Software Development.nproj
Model : Yes
FeatureModels : Yes
Configuration : Yes
Model(2)
[Warning](Multiplicity Constraint): The operand of the composite fragment (Interaction) violates the multiplicity limit of 1.
[Warning](Product Line): The feature name is not unique. Change the name or specify a unique name.
FeatureModels(1)
[Warning](Product Line): There are no selectable alternative features defined.
Configuration(1)
[Error](Product Line): "Feature" is a logical OR feature. Please select at least one logical OR feature at the same level.
Preparing the Command Line Extension
The following steps explain how to create a new command line extension project in Visual Studio and prepare a debugging environment for the command line extension.
- Creating a new project in Visual Studio
 - Installing the NuGet package for command line extension development
 - Creating a new class
 
This section explains the procedure for Visual Studio 2022 (VS).
Creating a new project in VS
This is similar to the Hello World example. See there.
| Item | Value | 
|---|---|
| Project Name | ModelValidationCliExtensionSample | 
| Location | Optional parent folder for storing the entire project | 
| Solution Name | ModelValidationCliExtensionSample | 
| Framework | .NET Standard 2.0 | 
- The project name must contain the string "CliExtension."
 - For details on project settings, see the following page.
 - Development Method > Developing Command Line Extensions > Project Settings
 
Installing Packages
Similar to the Hello World section. See there.
Build Settings
This is the same as the Hello World section. Please refer to the relevant section.
Creating a New Class
This is the same as the Hello World section. Please refer to the relevant section.
- Class Name: 
ModelValidationCliExtensionSample 
Implementing Command Processing
To implement the command line extension entry point and model validation processing, implement the following in the class created in Create a New Class.
- Declares the namespace of the API to reference.
 - A class that inherits the 
ExtensionBaseclass, which serves as the entry point. - Model validation command options.
 - Command handler for model validation.
 
Implementation Example
ModelValidationCliExtensionSample.cs
using NextDesign.Cli.ExtensionFramework;
using DensoCreate.Cli.Framework;
using NextDesign.Core.Runtime;
using NextDesign.Core;
using System.Collections.Generic;
using System.IO;
using System.Linq;
namespace ModelValidate.CliExtension
{
    ///<summary>
    ///An extension that provides model validation.
    ///</summary>
    public class ModelValidateExtension : ExtensionBase
    {
        ///<summary>
        ///Constructor
        ///</summary>
        public ModelValidateExtension()
        : base("NextDesign.ModelValidate")
        {
        }
    }
    ///<summary>
    ///Model validation command
    ///</summary>
    public class ModelValidateCommand : Command
    {
        ///<summary>
        ///Constructor
        ///</summary>
        public ModelValidateCommand()
        : base("ModelValidate", new string[] { "MV", "mv" }, "Command to perform model validation")
        {
            //Command option definition
            //Define using the DensoCreate.Cli.Framework.CommandBase.AddOption<T>() method.
            //<T>: Option type
            //First argument: Array of option names and aliases (e.g., "--projectPath", "-p")
            //Second argument: Option description (for displaying help information)
            //Third argument: Required option (true: required, false: optional)
            //ExistingOnly(): For FileInfo types, checks whether the specified file exists.
            AddOption<FileInfo>(new string[] { "--projectPath", "-p" }, "Project file path", true).ExistingOnly();
            AddOption<bool>(new string[] { "--doModelValidate", "--model", "-m" }, "Perform model validation");
            AddOption<bool>(new string[] { "--doFeatureValidate", "--feature", "-f" }, "Perform feature validation");
            AddOption<bool>(new string[] { "--doConfigurationValidate", "--configuration", "-c" }, "Perform configuration validation");
            //Register the command handler
            RegisterHandler(nameof(OnExecute));
        }
        ///<summary>
        ///Execute the command handler
        ///</summary>
        ///<param name="projectPath">Project file path</param>
        ///<param name="doModelValidate"></param>
        ///<param name="doFeatureValidate"></param>
        ///<param name="doConfigurationValidate"></param>
        private void OnExecute(FileInfo projectPath, bool doModelValidate = false, bool doFeatureValidate = false, bool doConfigurationValidate = false)
        {
            Console.WriteLine($"{Extension.Name}");
            Console.WriteLine($" Project : {projectPath}");
            Console.WriteLine($" Model : {(doModelValidate ? "Yes" : "Skip")}");
            Console.WriteLine($" Feature : {(doFeatureValidate ? "Yes" : "Skip")}");
            Console.WriteLine($" Configuration : {(doConfigurationValidate ? "Yes" : "Skip")}"); Console.WriteLine("");
            // Open the project
            // Get the NextDesign.Core.Runtime.IProjectService service
            // using the DensoCreate.Cli.Framework.ExtensionBase.GetService<T>() method,
            // and open the project using the IProjectService.OpenProject() method.
            var projectService = GetService<IProjectService>();
            var project = projectService.OpenProject(projectPath.FullName);
            if (doModelValidate)
            {
                project.Validate();
                var errors = project.GetAllErrorsWithChildren();
                OutputErrors("Model", errors);
            }
            if (doFeatureValidate)
            {
                var fms = project.ProductLineModel.FeatureModels;
                foreach (var fm in fms) fm.Validate();
                var errors = fms.SelectMany(fm => fm.GetAllErrorsWithChildren());
                OutputErrors("FeatureModels", errors);
            }
            if (doConfigurationValidate)
            {
                project.ProductLineModel.ConfigurationModel.Validate();
                var errors = project.ProductLineModel.ConfigurationModel.GetAllErrorsWithChildren(); OutputErrors("Configuration", errors);
            }
        }
        private void OutputErrors(string name, IEnumerable<IError> errors)
        {
            Console.WriteLine($"{name}({errors.Count()})");
            foreach (var error in errors.Take(10))
            {
                Console.WriteLine($" [{error.Type}]({error.Category}) : {error.Message}");
            }
            if (errors.Count() > 10)
            {
                Console.WriteLine(" :");
            }
            Console.WriteLine("");
        }
    }
}
Deploying to the Execution Environment
The set of files output to the publish folder as a build result is stored in the following folder.
- Windows version:
"%HOMEPATH%\AppData\Local\DENSO CREATE\Next Design CLI\extensions\ModelValidation\" - Linux version:
"$HOME/.local/share/DENSO CREATE/Next Design CLI/extensions/ModelValidation/" 
Running the command line extension
Execute the following command from the command prompt to output the model validation results to standard output.
- Example command with all options specified
 
ndcli ModelValidate --projectPath "{project file path}\Advanced Driving System Software Development.nproj" --model --feature --configuration
- Example command with feature and configuration validation specified
 
ndcli ModelValidate --projectPath "{project file path}\Advanced Driving System Software Development.nproj" --feature --configuration
License registration is required to run the command line extension. See the following page for details.