Generating Code

Chapter 4 - Generating Code From the Visio Model
byAndrew Filevet al.?
Wrox Press ©2002
Team FLY

Code is generated, and output to files, from the UML | Code | Generate menu:

click to expand

This command opens the Generate dialog window, shown in the screenshot opposite:

click to expand

In the Target language field the developer can choose the programming language, which becomes the output language for the code - if this disagrees with the choice of language made at any point in the diagramming phase, no error will be reported. We'll look more at this again in a moment.

In the right-hand side of the dialog window you can select namespaces and classes you want to export from your model to the resulting code.

After all the components are chosen - selecting the entire model selects each class in the model - and the programming language to be used is chosen, we can launch the generating process by clicking the OK button. If the directory into which you wish to generate the code does not exist, you will be asked if the directory should be created for you:

Remember the Target Language field that we saw in each of the earlier Code Generation Options dialogs? Well, it turns out that any language choices you made there are irrelevant to the final code generation from the UML | Code | Generate menu.

The choice of language that you make in the Target Language field of the Generate dialog that we saw above determines the language for each class, attribute, and operation involved in the code generation process.

Thus if you choose C# from the Generate dialog but have the target language for some of your methods set as Visual Basic (.NET), then they will still be generated as C#.

The code will be generated and put into the file we specified from the Location field, ready to be added to our projects. Note that the code generating procedure allows us to add the generated code to Visual Studio .NET projects automatically by checking the Add Classes to Visual Studio Project checkbox. With this checkbox checked, the Template drop-down becomes active, and it contains a list of the Visual Studio .NET project types into which the generated code will be added. All possible types of Visual Studio .NET projects are listed. If you want to add your classes to a web project - Empty Web Application, ASP.NET Web Application, or ASP.NET Web Service, then you have to specify a valid URL for the project, rather than a filename, just as you would in Visual Studio .NET.

Code will be generated for each selected class, and will go into a separate file with the name of the class followed by the extension for that language. There are three files created for our example, Employee.cs, Person.cs, and DateTime.cs. Employee.cs contains the code for the Employees class, the Person interface code is in Person.cs, and the System. DateTime code is in DateTime.cs - this file only contains the class definition, since we didn't do anything else to the class.

Here's Employee.cs:

    // Static Model    using System;    public class Employee    : Person    { 

Here we can see the using directive for the System namespace - this comes from the System package that contained the DateTime structure. We can also see that the Employee class is indeed implementing the Person interface.

        private int id;        private System.DateTime hireDate;        private decimal salary; 

Here we have our private fields, and the public members are next - note the read-only properties ID and Salary:

        public string FirstName        {            get            {            }            set            {            }        }        public string LastName        {            get            {            }            set            {            }        }        public DateTime BirthDate        {            get            {             }             set             {             }        }        public int ID        {            get            {            }        }        public decimal Salary        {            get            {            }        }        public DateTime HireDate        {            get            {            }            set            {            }        } 

Next up is our pre-populated ChangeSalary() method, with the information that we specified in the Documentation box added as a comment:

         // Changes the salary of the employee         public void ChangeSalary(decimal amount)         {             salary += amount;         }   }//   END CLASS DEFINITION Employee 

You may be wondering why the code has been organized so - we'll see why in a moment.

Here is the code in Person.cs for the Person interface, with its properties:

    // Static Model    using System;    public interface Person    {        string FirstName        {           get;           set;        }        string LastName        {           get;           set;        }        DateTime BirthDate        {           get;            set;        }    }// END INTERFACE DEFINITION Person 

Regenerating Code

Generating code again will not overwrite an existing file - any existing files that would be overwritten are renamed to <classname>~1 followed by the language extension, and the new code is always of the form <classname> with the language extension.

Thus generating the code again for our example would rename Employee.cs to Employee~1.cs and Person.cs to Person~1.cs, and the new code files would be Employee.cs and Person.cs. Subsequent generations would see Employee~1.cs and Person~1.cs renamed to Employee~2.cs and Person~2.cs, and so on, so that existing code is never overwritten.

Checking Errors

We can investigate any errors that would be produced in the code generation process by first selecting the UML | Check menu item. This command activates the Output window, which is shown below:

click to expand

In the drop-down list situated in the top part of the Output window, you can choose the kind of errors to be shown.

If the Errors element is chosen, then the error messages about the semantic errors in UML model will be shown. Semantic errors indicate invalid constructions in UML 1.2. For example, in UML you can't use interfaces as parameter types. The offending classes that contain these errors will be highlighted in red on the diagram.

If the Code element is shown, then the error messages about possible errors in generated code will be shown. Code errors indicate invalid constructions in the target language. For example, in C# and in Visual Basic .NET you cannot have multiple inheritance:

click to expand

Here we've modified the Employee class to inherit from more than one class - as you can see, the offending class is named in the Output window, and if you the click on the error line then the offending class is highlighted in the diagram.

Code Generation in Different Languages

We have seen how code generation works with C#, but let's take a moment to see compare the code generated for our Employee class in Visual Basic .NET with that in C#. We'll see that although Visio can generate code to other languages, the language-specific choices you make when creating the model have consequences.

Here is the Visual Basic .NET code for the Employee class, as generated by Visio:

    ' Static Model    Imports TopPackage.System    Public Class Employee           Implements Person       Private id As Integer       Private hireDate As System.DateTime       Private salary As Decimal       Public Function FirstName () As String Implements Person.FirstName       End Function       Public Function LastName () As String Implements Person.LastName       End Function       Public Function BirthDate () As DateTime Implements Person.BirthDate       End Function       Public Function ID () As Integer       End Function       Public Function Salary () As Decimal       End Function       Public Function HireDate () As DateTime       End Function          ' Changes the salary of the employee       Public Sub ChangeSalary (ByVal amount As Decimal)          salary += amount;       End Sub     End Class ' END CLASS DEFINITION Employee 

Take a look at this code. There are two problems here - the first is the Imports statement:

    Imports TopPackage.System 

This is not the namespace we want imported - we want System imported. This is a peculiar behavior of Visio. When we generated code for the C# project, the Default Namespace property was set to TopPackage - this property does not affect existing code. It is only used during the creation of new files, when this property is applied to set up a namespace.

In the Visual Basic .NET project the Root namespace property is set to TopPackage, but this property has a different meaning from the C# Default Namespace - in the Visual Basic .NET project any namespace is prefixed with TopPackage during compilation. Thus if you have the namespace System55 in your code, it compiles to TopPackage.System55. Therefore, Visio will generate System.DateTime to TopPackage.System.DateTime. This is a curiosity, and hopefully one that will be corrected in future releases.

The other problem is the code in the ChangeSalary() method body - it's still C#.

     Public Sub Changesalary (ByVal amount As Decimal)           salary += amount;         End Sub 

Any code that we explicitly add to method bodies will be inserted into generated code files without modification, regardless of the language used for generation. In this situation, our Visual Basic .NET code will not compile.

You should always remember that the closer the you take your model to a particular language by including language-specific code or operations, the more you tie yourself to that particular language.

Team FLY


Professional UML with Visual Studio. NET. Unmasking Visio for Enterprise Architects
Professional UML with Visual Studio. NET. Unmasking Visio for Enterprise Architects
ISBN: 1440490856
EAN: N/A
Year: 2001
Pages: 85

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net