1. Architecture Lab |
Overview: You'll work with the command-line tools of .NET to create and explore console-based applications. First we'll create a monolithic application, then a component-based one.
Part 1: Monolithic Application
First, open a command window that has the path variables to the .NET Framework SDK set appropriately. The best way is via Start menu, Programs, Microsoft Visual Studio .NET, Visual Studio .NET Tools, and then select Visual Studio .NET Command Prompt.
Change directory (cd) to where you installed the Labs directory, cd into "1-Architecture", and then cd into "work". This is the work directory for the lab assignment.
Using your favorite editor (Notepad?), create a text file called "main.cs". Write a C# program that outputs a simple message to the console. Compile with csc and run.
Next, let's automate the compilation process using a makefile. Create a text file called "makefile" with the following contents (note that you can copy the text below to the clipboard and paste it into your text editor window):
app.exe: main.cs
csc /t:exe /out:app.exe main.cs
Close the file. List the contents (dir) of your directory and make sure your file is called "makefile", and not "makefile.txt" (rename with ren if so). Now you should be able to run "nmake app.exe" to compile your program. From this point on you are encouraged to maintain and use the makefile for compiling your programs.
Let's write a little OOP-based code. Create a Customer class with 2 string fields, one for their first name and one for their last name. Code the default constructor (i.e. the constructor with no parameters) to prompt the user for the customer's first and last names; you can use System.Console.Write("...") for prompting, and System.Console.ReadLine() for inputting. Note that ReadLine() returns the entire line of input as a single string, so you'll want to input the first and last name individually. Finally, implement a ToString() method that concatenates and returns the customer's full name; use the "+" operator for string concatenation.
Modify the main program to create a Customer object and then output the object to the console using System.Console.WriteLine() and the object's ToString() method. Compile as a monolithic application (i.e. compile the main and class files together with csc), run, and test.
Modify the main program to create 3 different Customer objects, output a blank line, and then output the 3 customers.
Run the .NET disassembler tool ILDasm on your application, "ildasm app.exe", and browse the compiled assembly. Open the manifest, and then open each of the types (classes) in your program (there should be two, one for Customer and one for the class containing your main program).
Part 2: Component-based Application
Without changing the source code, rebuild the application as a component-based one. First, extend your makefile with an additional command to compile the Customer class as a library assembly:
customer.dll:
customer.cs
csc /t:library /out:customer.dll customer.cs
Second, modify the makefile to compile the main program so that it references the Customer assembly, instead of compiling the Customer class directly. Finally, build the application by first compiling the Customer assembly, and then compiling the application; if "nmake" reports that app.exe is up-to-date (which it technically is since the source code hasn't changed), note that you can use the /A option of nmake to force recompilation.
Run and test, and convince yourself that the application performs exactly as before. Of course, internally the application has been built quite differently than before. To convince yourself of the difference, reopen the application file using ILDasm ("ildasm app.exe"). First, notice that the manifest now contains an external reference to the Customer assembly. Second, notice that the Customer class is now missing from app.exe.
Rename the Customer assembly to something like "customer.xyz". Now try to run the application, it should fail with an exception (answer No when asked about JIT debugging). The CLR is reporting that is was unable to find the required Customer assembly. Rename the assembly back to "customer.dll", and the application should work as before.
One of the advantages of component-based development is that components can be updated independently of each other. Modify the Customer class by changing what the ToString() method returns, for example by returning the customer's name with the phrase " is a customer" appended to the end. Recompile only the Customer assembly, and rerun the application. The application should now behave differently, given the modification you made to the Customer class.
If time permits...
Modify the main program to output the 3 customers in alphabetical order, based on their ToString() values. Nothing fancy, just use a series of if statements to sort the customers in a brute force way.. However, note that you cannot compare strings using the traditional < or > operators. Instead, strings are objects which are compared by calling their CompareTo() method, like this:
string s1, s2;
s1 = ...;
s2 = ...;
if (s1.CompareTo(s2) < 0) // s1 < s2
...;
else if (s1.CompareTo(s2) == 0) // s1 = s2
...;
else
// s1 > s2
...;
In other words, obj1.CompareTo(obj2) returns an integer denoting whether obj1 <, =, or > obj2.
Add a method to the Customer class which returns the length of the customer's full name, i.e. the total number of characters in their first and last names. Then have the main program output the length as well as each customer's name. The length of a string is easily computed through a member of the string class; open the Microsoft Visual Studio .NET Documentation (available via Start menu, Programs, Microsoft Visual Studio .NET), switch to the Index tab, and "Look for" the String class; you can narrow the search results if you "Filter by" the .NET Framework.