There are some tasks (commands) that require maximum automation and minimum user interaction. In general, such conditions are satisfied by a console application that allows a user to specify the command, set parameters and start execution. Of course, all this should be implemented as an organic part of a XAF application, i.e. command is a function of the application, it is coded in the XAF module. Xafari framework proposes an architecture to implement commands and supplies RunCmd.exe console application to execute commands. The framework provides a number of implemented commands: to import (export) data, to create report etc.
This post describes how to apply this mechanism.
Create XAF WindowsFormApplication, name it RunCmdExample. Add BO business class to the RunCmdExample Module project. The following code demonstrates this.
1 2 3 4 5 6 7 8 | [DefaultClassOptions] public class BO : BaseObject { public BO(Session session) : base(session) { } public string Name { get; set; } public string Description { get; set; } } |
Set Security System as you can see in the application screenshots:
Set LogonParametersType to the "DevExpress.ExpressApp.Security.ChangePasswordOnLogonParameters".
Add a new
Add RunCmdExample Module to the CommandModule. You can do it in the code or use designer. If you wish to add an extra module in the code, use the following code snippet:
1 2 3 4 | private void InitializeComponent() { this.RequiredModuleTypes.Add(typeof(RunCmdExample.Module.RunCmdExampleModule)); } |
Add reference to the Xafari.dll assembly and set CopyLocal property to "True".
Now we can implement two commands. Add two command classes to CommandModule: it is SecurityInformation and DataInformation. SecurityInformation command will display a list of users or roles. SecurityInformation command will display determined columns of BO type from the database.
The following code snippet defines SecurityInformation and DataInformation classes:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 | public class SecurityInformation : CommandExtIOBase { public override string Description { get { return "SInfo command shows information about Roles and Users from DataBase"; } } protected override void ExecuteCore(IDictionary parameters) { var parameterValue = parameters["Param"].ToString(); if (parameterValue.Equals("Users", StringComparison.OrdinalIgnoreCase)) DisplayUsers(); else if (parameterValue.Equals("Roles", StringComparison.OrdinalIgnoreCase)) DisplayRoles(); else Out.WriteLine("Invalid parameter value!"); } private void DisplayRoles() { Out.WriteLine("\nRoles:"); var roles = Application.CreateObjectSpace().GetObjects(); foreach (var role in roles) Out.WriteLine(" {0}", role.Name); } private void DisplayUsers() { Out.WriteLine("\nUsers:"); var users = Application.CreateObjectSpace().GetObjects(); foreach (var user in users) Out.WriteLine(" {0}", user.UserName); } public override string Name { get { return "SInfo"; } } public override IEnumerable ParametersDescription { get { yield return new CommandParameterDescription("Param", ", ", "Show information about Roles and Users from DB."); } } public override void ValidateParameters(IDictionary parameters) { base.ValidateParameters(parameters); var tableName = parameters["param"].ToString(); if (!tableName.Equals("Users", StringComparison.OrdinalIgnoreCase) && !tableName.Equals("Roles", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException(string.Format("Недопустимое значение параметра Param:\"{0}\"", tableName)); } } private IObjectSpace objectSpace { get; set; } } public class DataInformation : CommandExtIOBase { public override string Description { get { return "DInfo command shows information about BO object from DataBase"; } } protected override void ExecuteCore(IDictionary parameters) { var parameterValue = parameters["Column"].ToString(); if (parameterValue.Equals("Name", StringComparison.OrdinalIgnoreCase)) DisplayNameColumn(); else if (parameterValue.Equals("Description", StringComparison.OrdinalIgnoreCase)) DisplayDescriptionColumn(); else if (parameterValue.Equals("All", StringComparison.OrdinalIgnoreCase)) DisplayAllColumns(); else Out.WriteLine("Invalid parameter value!"); } private void DisplayAllColumns() { if (objectSpace == null) objectSpace = Application.CreateObjectSpace(); var businesObject = objectSpace.GetObjects(); Out.WriteLine("\n{0,-20} {1}", "Name:", "Description:"); foreach (var obj in businesObject) Out.WriteLine(" {0,-20} {1}", obj.Name, obj.Description); } private void DisplayDescriptionColumn() { if (objectSpace == null) objectSpace = Application.CreateObjectSpace(); var businesObject = objectSpace.GetObjects(); Out.WriteLine("\nDescription:"); foreach (var obj in businesObject) Out.WriteLine(obj.Description); } private void DisplayNameColumn() { if (objectSpace == null) objectSpace = Application.CreateObjectSpace(); var businesObject = objectSpace.GetObjects(); Out.WriteLine("\nName:"); foreach (var obj in businesObject) Out.WriteLine(obj.Name); } public override string Name { get { return "DInfo"; } } public override IEnumerable ParametersDescription { get { yield return new CommandParameterDescription("Column", ", , ", "Show content of BO object current column from DB."); } } public override void ValidateParameters(IDictionary parameters) { base.ValidateParameters(parameters); var tableName = parameters["Column"].ToString(); if (!tableName.Equals("Name", StringComparison.OrdinalIgnoreCase) && !tableName.Equals("Description", StringComparison.OrdinalIgnoreCase) && !tableName.Equals("All", StringComparison.OrdinalIgnoreCase)) { throw new ArgumentException(string.Format("Недопустимое значение параметра Column:\"{0}\"", tableName)); } } private IObjectSpace objectSpace { get; set; } } |
The CommandModule must support ICommandEnumerator interface to specify commands for the Run Cmd utility. Otherwise, Run Cmd will not "know" about the implemented commands. Add the following code to the CommandModule:
1 2 3 4 5 6 7 8 | public IEnumerable Commands { get { yield return new SecurityInformation(); yield return new DataInformation(); } } |
For ease of use in the future, add RunCmd.exe and RunCmd.exe.config files to the CommandModule project directory. Xafari installer places these files in the "…\Xafari Framework \Tools\RunCmd\" directory.
RunCmd.exe.config settings must match the settings of the global application.
The presence of the <system.diagnostics> block allows logging the execution process.
When working with Run Cmd, it is very convenient to use .bat-file. Add Run.bat file to the project and place following text in it:
1 2 3 4 5 6 7 8 9 10 11 | @echo. RunCmd.exe /dbupdate silent /h /cmdlist @echo. RunCmd.exe @sinfo.txt @echo. RunCmd.exe /batch dinfo.txt |
The example above demonstrates different ways to set commands: to type in the command line and to load from file.
dinfo.txt file contains:
1 2 3 4 5 | DInfo Column:All DInfo Column:Name DInfo Column:Description |
These commands retrieve information from the database at the specified column. The image illustrates the result of these commands.
cinfo.txt file contains:
1 | /paramlist SInfo /c SInfo Param:Users /c SInfo Param:Roles |
The image illustrates the result of SInfo commands.
Before running the utility, you must build CommandsModule, build and run the application to populate the database.
Load solution: Run Cmd Example.