Beruflich Dokumente
Kultur Dokumente
M I C R O S O F T
L E A R N I N G
P R O D U C T
6367A
Introduction to Object-Oriented Programming with Microsoft Visual Studio 2008 Companion Content
Information in this document, including URL and other Internet Web site references, is subject to change without notice. Unless otherwise noted, the example companies, organizations, products, domain names, e-mail addresses, logos, people, places, and events depicted herein are fictitious, and no association with any real company, organization, product, domain name, e-mail address, logo, person, place or event is intended or should be inferred. Complying with all applicable copyright laws is the responsibility of the user. Without limiting the rights under copyright, no part of this document may be reproduced, stored in or introduced into a retrieval system, or transmitted in any form or by any means (electronic, mechanical, photocopying, recording, or otherwise), or for any purpose, without the express written permission of Microsoft Corporation. Microsoft may have patents, patent applications, trademarks, copyrights, or other intellectual property rights covering subject matter in this document. Except as expressly provided in any written license agreement from Microsoft, the furnishing of this document does not give you any license to these patents, trademarks, copyrights, or other intellectual property. The names of manufacturers, products, or URLs are provided for informational purposes only and Microsoft makes no representations and warranties, either expressed, implied, or statutory, regarding these manufacturers or the use of the products with any Microsoft technologies. The inclusion of a manufacturer or product does not imply endorsement of Microsoft of the manufacturer or product. Links may be provided to third party sites. Such sites are not under the control of Microsoft and Microsoft is not responsible for the contents of any linked site or any link contained in a linked site, or any changes or updates to such sites. Microsoft is not responsible for webcasting or any other form of transmission received from any linked site. Microsoft is providing these links to you only as a convenience, and the inclusion of any link does not imply endorsement of Microsoft of the site or the products contained therein. 2010 Microsoft Corporation. All rights reserved. Microsoft and the trademarks listed at http://www.microsoft.com/about/legal/en/us/IntellectualProperty/Trademarks/EN-US.aspx are trademarks of the Microsoft group of companies. All other marks are property oftheir respective owners.
1-1
Module 1
Getting Started with Object-Oriented Programming
Contents:
Lesson 1: Introduction to Object-Oriented Programming Lesson 2: Creating Projects in Visual Studio 2008 Lesson 3: Coding in Visual Studio 2008 Lesson 4: Productivity Features in Visual Studio 2008 Lesson 5: Debugging Visual Studio Applications Module Reviews and Takeaways Lab Review Questions and Answers 2 6 11 14 19 23 25
1-2
Lesson 1
1-3
1-4
Additional Reading
Support for Object-Oriented Development in .NET and Visual Studio 2008
Visual Studio 2005 Class Designer Object Browser Object Test Bench Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects
1-5
Lesson 2
1-6
1-7
Modify the properties as required, and then click OK. A new project will be created for you. Take note of the following features: a. b. c. There is a menu structure at the top of the application (File, Edit, View ), and a toolbar directly below. In the center of the page is the design canvas where you design the application interface. In our case, this is a Web form named Default.aspx. Left of the form is the toolbox. Click the toolbox so that it expands, and notice the variety of controls. These are controls for a Web form, and that the controls for a windows form are different. In the top, right corner, highlight the solution explorer. The tree-view makes it easy to access all solution components. Note the following files that are created by this project template: i. ii. iii. Default.aspx: The first Web form of the application. Expand the tree and note the codebehind files (.cs or .vb files). config file: The .xml file for storing Web site configuration settings. Lastly, note the Properties window on the bottom, right corner. The currently selected objects properties are displayed in the window.
d.
6.
You currently have a solution with a single project. In most real world solutions the solution consists of multiple projects. To add a Web site to the solution, click File, click Add, and then click New Web Site. On the dialog box ensure ASP.NET Web Site is selected. Keep the other default settings, but select the language of your choice and then click OK. A new Web site adds to the solution. Note that a Web site is a simple ad-hoc Web site, whereas a Web application has all the makings of a Visual Studio 2008 project. You can demonstrate this by showing the properties differences of the last two projects. a. b. Right-click the Web site project, and then click property pages. Take note of the items available, and then close the window. Right-click on the Web application, and then select properties. Click the tabs, and take note of the large number of settings that are available. Close the Properties window.
7.
1-8
8.
Add a class library project to the solution. Click File, click Add, and then click New Project. Under Project Types, select the language of your choice, and then click Windows. Select Class Library as the template. Change the name to ClassLibraryDemo, and then click OK. A new class library adds to the solution, and class1 should open in the code view.
9.
10. To add a Windows Forms Application, click File, click Add, and then click New Project. Under Project Types, select the language of your choice, and then click Windows. Select Windows Forms Application as the template. Change the name to WindowsFormsDemo, and then click OK. 11. A new Windows Forms application will be added to the solution, and form1 will display in the designer. Review the files that have been created for this project. 12. Right-click Class1 in the ClassLibraryDemo project, and select View Code. In Class1, write a method that will take a string as input and return it in the uppercase. 13. Right-click the WindowsFormsDemo and select Add Reference. Click the Projects tab, click ClassLibraryDemo and then click OK. Switch to Form1 in designer mode, and then drag and drop a button and textbox control onto the form. Change the text property of the button to Click Me. Double-click on the button, and add code that will instantiate an instance of the ClassLibraryDemo. Call the ChangeToUpper method with the contents of the text box, and then display the result in a messagebox. 14. Right-click the WindowsFormsDemo, and then click Set as startup project. 15. On the menu bar, click Build, and then click Build Solution. Ensure that the build succeeds, Notice the status is in the bottom left of the window. 16. Press the F5 key to start executing the project. 17. When the form loads, type hello world into the text box, and then click the Click Me button. The text HELLO WORLD should display in the message box. Stop executing the application. 18. Optional: If you have time, you can repeat a similar exercise with the Web application. 19. Leave the current solution open for the next demonstration.
1-9
Additional Reading
Visual Studio Project Types
Default Project Templates in Visual Studio
Web Projects
Web Application Projects Overview Comparing Web Site Projects and Web Application Projects
1-10
Lesson 3
1-11
Defining Collections
Question: What is the benefit of using a generic collection? Answer: A generic collection can store any type, but you specify the type to store when you instantiate the collection. This makes the collection type-safe.
Controlling Flow
Question: When should you use an IF statement instead of a SELECT/SWITCH? Answer: Use an IF statement if multiple variables and factors will determine what code to execute. A SELECT/SWITCH statement can only examine a single variable to determine the appropriate path to follow.
Type Conversion
Question: Why should you explicitly convert your data types? Answer: If you rely on .NET to convert your data types, you may have unexpected results because.NET may not convert types the way you expect. For example, if you try to add two string variables that contain integers, .NET will concatenate the strings when you may want the two strings to be converted to integers and then added together.
Generic Types
Question: What is the value of using a generic collection? Answer: Generic collections provide type safety so you control the types that can be stored in the collection at runtime.
1-12
Additional Reading
Value Types
Value Types in the Common Type System .NET Type Fundamentals
Reference Types
.NET Type Fundamentals
Defining Collections
System.Collections.Generic Namespace
Type Conversion
IConvertible Interface Casting and Type Conversions (C# Programming Guide) How to: Convert a string to an int (C# Programming Guide) Converting Types
1-13
Lesson 4
1-14
1-15
An XML code snippet will be inserted to create a template for comments. In the summary element, type This function receives a string as input and then returns it in the uppercase. Within the ChangeToUpper function, add a comment by completing one of the following steps: a. b. If using Visual Basic, add the following line: This line returns the value. If using Visual C# add the following line: //This line returns the value.
4.
2.
Build the project. Navigate to the bin\debug\ folder, and then open the ClassLibraryDemo.xml file. Highlight the comments that have been placed in the XML file.
Note: the normal inline comments are not added, only the summary comments.
3.
1-16
inserted into the function. Edit the code snippet so that your function looks like the following:
Public Function ChangeToUpper(ByVal input As String) As String If input.Length > 0 Then This line returns the value Return input.ToUpper() Else Return End If End Function
b. c.
If using Visual C#: Above the line that returns the value, right-click and select Insert Snippet, double click Visual C#, double click and select if (not #if), and then double click. You should notice a code snippet being inserted into the function. Edit the code snippet so that your function looks like this:
public string ChangeToUpper(string input) { if (input.Length > 0) { //This line returns the value return input.ToUpper(); } else { return ; } }
Refactoring code
1. Return to the ChangeToUpper function, and rename the functions input parameter to inputstring. You will notice a red underscore under the renamed variable which is different than the red underlines under the broken references to the variable. Mouse over the red underscore at the end of inputstring and then over the refactoring icon that appears. Click the down arrow, and then select Rename input to inputstring. The input variable in the code block will be renamed to inputstring. If Refactoring Warning dialog box appears, click Continue. Leave the solution open for the next demonstration.
2. 3.
1-17
Additional Reading
Coding Productivity Features in Visual Studio 2008
XML Documentation Comments (C# Programming Guide) Whats new in Visual Studio 2008 Using IntelliSense
1-18
Lesson 5
1-19
Test Projects
Question: What is the benefit of creating a test project? Answer: Taking the time to create a test project when you first do testing will save time later, because you will be able to quickly retest any code changes by re-executing the existing tests.
1-20
3.
2.
2. 3. 4. 5.
2. 3.
1-21
4.
5.
[Visual C#]
[TestMethod()] public void ChangeToUpperTest() { Class1 target = new Class1(); string inputstring = Hello World; string expected = HELLO WORLD; string actual; actual = target.ChangeToUpper(inputstring); Assert.AreEqual(expected, actual);
[Visual Basic]
<TestMethod()> _ Public Sub ChangeToUpperTest() Dim target As Class1 = New Class1 Dim inputstring As String = Hello World Dim expected As String = HELLO WORLD Dim actual As String actual = target.ChangeToUpper(inputstring) Assert.AreEqual(expected, actual) End SubEnd Sub
6. 7.
Place a breakpoint on the first line of the test method. Place the cursor in the test method. From the menu bar, click Test, click Debug, and then click Tests in current context. The code will start executing and break into debug mode when it reaches the break point. Step through the code and into the target.ChangeToUpper method. Place the cursor over the inputstring input parameter, and view the current valued. Step through the rest of the code in the method. When you return to the test method, right-click the actual variable and select Quick Watch. Review the values in the window, and then close it.
8.
1-22
9.
Continue stepping through the code. The test should pass. You should see the test as passed in the test results window at the bottom of the screen.
10. Change the expected string value to Hello world (H is uppercase). Rerun the test. This time the result should be a fail. 11. Save and close the project.
1-23
What features are offered in Visual Studio 2008 to help you create, maintain, and document your code? Answers will vary, but may include: XML documentation, unit testing, and code snippets.
The /doc option was not specified when compiling the project, or the Generate XML Documentation property was not set in the project properties.
The Assert.Inconclusive(Verify the correctness of this test method.) was not removed from the generated unit test code.
1-24
3.
You have finished writing and testing the code for a class. Your code is sent back by the testing team because they have identified a bug. What feature should you use to speed up retesting your code after making the fix? Add a test project with methods to test your code.
Best practices related to developing an object-oriented application with Visual Studio 2008
Supplement or modify the following best practices for your own work situations: Use Test projects to unit test your code, so you can quickly retest all of your code whenever you make any modifications. Document your code within the project using comments or the XML documentation feature, so that anyone who has to maintain your code has access to documentation explaining the code. Take the time at the beginning of the project to think about object-oriented design, to create an elegant re-usable application that is easier to maintain. Set Option Strict=On for Visual Basic applications to ensure you do not implicitly convert one data type to another and lose data through narrowing.
Tools
Tool Class Designer Class View Object Browser Use for Documenting your class design and generating Code Browse the classes within your project Browse all the namespaces available to your project Where to find it
1-25
Can you name three methods to view the value of a variable while debugging? Answer: While in debug mode you can: a. b. c. Place the cursor over the variable Create a watch or quick watch Use the immediate window to query the variable
4.
Is it possible to set conditions on a break point? Answer: Yes it is. For example, when a specific value changes, or when a certain line of code is hit a certain number of times.
2-1
Module 2
Implementing Classes, Properties and Methods
Contents:
Lesson 1: Creating Classes Lesson 2: Implementing Properties within a Class Lesson 3: Implementing Methods within a Class Lesson 4: Using Class Properties and Methods Module Reviews and Takeaways Lab Review Questions and Answers 2 6 9 13 16 18
2-2
Lesson 1
Creating Classes
Contents:
Question and Answers Additional Reading 3 5
2-3
Class Lifecycle
Question: What is the difference between allocation and instantiation? Answer: Allocation allocates the memory for the class, whereas instantiation initializes the class by running the constructor method of the class.
Namespaces
Question: How do you access a class that is in a namespace from your client code? Answer: Either specify the fully qualified name of the class, or import the namespace with the statement Imports (Visual Basic) or using (Visual C#). Question: Why would two classes be in the same namespace?
2-4
Answer: When two classes share something in common, they can share the same namespace.. A Savings Account class and a Checking Account class are both classes that are used to manage bank accounts.
2-5
Additional Reading
Introduction to Classes
Class Lifecycle
Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework Garbage Collection
Class Attributes
2-6
Lesson 2
2-7
2-8
Additional Reading
Defining Class Properties
2-9
Lesson 3
2-10
Overloading
Question: Can you think of a situation where you might use overloading? Answer: Answers will vary. One example is on a method used to retrieve an error message for a multilingual application. One version of the method accepts an error code and returns the error message for the default language, while an overloaded version of the method accepts an error code and a language code, and returns the error message for the specified language. Question: Can you have an overloaded method one of which accepts name and id, the other one accepts id and name? Answer: Yes, as long as name and id are different data types, putting the parameters in a different order is considered a different signature. Question: In Visual Basic, you can have optional parameters. Can you have overloaded methods, one of which accepts name and an optional parameter id, and the other just accepts name? Answer: No, since both methods can accept a single string parameter, the signatures are considered the same. Question: Can you have an overloaded method, one of which accepts name and id, the other one accepts id and name? Answer: Yes as long as name and id are different data types, putting the parameters in a different order is considered a different signature.
Accessors
Question: Can you think of a situation where a method in a class would not be declared as public?
2-11
Answer: Answers will vary. One example is when you write a method to perform a calculation that is only used within the class.
2-12
Additional Reading
Overloading
Operator Overloading Usage Guidelines Operator Overloading Tutorial
2-13
Lesson 4
2-14
2-15
Open the Product class in the Products project in the code view. In the code window you will see two properties defined: ProductID, and ProductPrice. Notice the use of different data types, and which declarations are public and which are private. In the Product class, create a property named ProductName (string) by using a code snippet. (Type prop and press the TAB key twice.) Create a read-only property by un-commenting the RetailPrice property. Highlight the differences between this and a read and write property. Uncomment the first SetRetail method, and review the code. (Do not uncomment the second method as it is used for a later demonstration.) Open the Module2Demo project and add a code reference to Products class library. This is necessary to access the properties and methods of the class library. Open Form1 in the Module2Demo project in the code view, and then navigate to the Button1_Click event handler. Uncomment and review the code. This code creates an instance of the product class and then sets the various properties. Press F5 to execute the application. Click the Create Product button. You should see a message box that displays property values. The code behind the Increase Price (%) button increases the retail price of the product by 10%. Click the button and wait for the execution.
3. 4. 5. 6. 7.
8. 9.
10. Stop the program execution, and return to the Product class. Review the concept of overloading methods, and then uncomment the code for the second method. 11. Return to the code view of Form1 and uncomment the code in Button3_click event handler. Review the code. 12. Press F5 to run the application, and then click the Create Product button and each of the increase price buttons. Review the result. 13. Stop the application from executing. Return to the Product class and review the code for SetTax method. Highlight that it is defined as shared, also the declaration for the _TaxValue variable at the top of the class. 14. Return to the code view of Form1, and uncomment the code in Button4_click event handler. Review the code. 15. Press F5 to run the application and then click on the Shared/Static Demo. Review the results.
2-16
Issue When I declare a variable to hold my class, the intellisense does not display all the methods and properties I defined in the class. My application is running out of memory. I thought the garbage collector cleaned everything up for me. I found a code example that creates a SqlConnection object, but I do not see anywhere in the code where the connection string is specified for the object. How can it connect without a connection string?
Troubleshooting tip
You have allocated the class, but have not instantiated the class. The garbage collector only releases managed resources. Unmanaged resources such as files need to be released in a finalize or dispose method There is a constructor method for the SqlConnection object that accepts the connection string as a parameter, and sets the property based on the parameter.
2-17
2-18
Is it possible to set conditions on a break point? Answer: Yes it is, for example when a specific value changes, or when a certain line of code is hit a certain number of times.
3-1
Module 3
Implementing Inheritance, Abstraction, and Polymorphism
Contents:
Lesson 1: Introduction to Inheritance and Abstraction Lesson 2: Implementing Inheritance and Abstraction Lesson 3: Introduction to Polymorphism Lesson 4: Implementing a Polymorphic Structure Module Reviews and Takeaways Lab Review Questions and Answers 2 4 9 11 16 18
3-2
Lesson 1
3-3
Benefits of Inheritance
Question: In a procedural language, how do you achieve the benefits of inheritance listed above? Answer: Answers will vary, but generally you use modular code in the form of reusable modules. However, the code that calls the reusable modules is often very dependent on what has been written within the module. Also, the structure created in procedural code does not usually model real life as closely as inheritance.
3-4
Lesson 2
3-5
Shadowing
Question: What is the risk associated with hiding and shadowing? Answer: You may accidentally replace functionality in the base class that needs to be executed. Question: What might be an example of Shadowing? Answer: Answers will vary. When a base class offers a lot of functionality, and the derived class needs to be simplified, then shadowing can offer a benefit.
Sealing
Question: What might be another example of when to implement a Sealed class? Answer: Answers will vary, and will depend on the business rules. In some banks a SavingsAccount might be a sealed class because the only accounts offered are Checking and Savings accounts, and that is the class that should always be instantiated. In another bank the SavingsAccount class might not be sealed, because it is inherited by a HighInterestSavingsAccount class or a JuniorSavingsAccount class.
3-6
Visual C#: E:\Demos\Mod03\Starter\CS\Mod03Demo\Mod03Demo.sln Open the Animal class in the code view, and review the class definition. Open Form1 in the code view, and navigate to the btnDemo1_Click method. Review the definition of the Animal class, and use IntelliSense to demonstrate the available properties and methods of the class. Open the Wolf class in the code view, and review the code. Notice that this class inherits from the Animal class, and that this class has an additional property (Color) defined. Return to the btnDemo1_Click method in Form1, and review the code definition for the Wolf class. Use IntelliSense to demonstrate that the Wolf class contains the properties and methods of its base class as well as the derived class. Press Ctrl+F5 to execute the application. Once the form has been loaded, click the Inheritance button. You should see a message box displaying values from the base and inherited classes. Stop the program application.
5. 6.
7.
3-7
Visual C#: E:\Demos\Mod03\Starter\CS\Mod03Demo\Mod03Demo.sln Open the Animal class in the code view, and review the class definition. Specifically, notice the constructor. Open the Wolf class in the code view, and review the code. Specifically, notice the draw constructor. Return to the btnDemo1_Click method in Form1, and place a breakpoint in the first line of executable code. Press the F5 key to run the application. Wait for the form to load, and then click the Inheritance button. Step through the code, and make sure you see the messages written to the Immediate window, which will demonstrate the sequence in which the base and derived class constructors are called. Stop the program execution.
6.
3-8
Additional Reading
Implementing Inheritance
Inheritance Basics
3-9
Lesson 3
Introduction to Polymorphism
Contents:
Question and Answers 10
3-10
3-11
Lesson 4
3-12
Polymorphic Methods
Question: Can you think of an example where a method is implemented differently in the derived class than in the base class? Answer: Answers will vary, but one example is a bank account and a savings account. A Withdraw method would be defined in the base class bank account, since all account types need to support withdrawing funds. The savings account might charge a transaction fee when a withdrawal is made, so it will implement different functionality for the Withdraw method than its base class bank account. Question: In the example above, does every class have to have override the stop method? Answer: No, only if a better method can be provided. If the derived class does not override the base class, then the version of the method in the base class will be called.
3-13
Answer: No, you cannot override it, but you can use hiding and shadowing to change the code executed when you use that method name in the derived class. Question: How do you handle a situation where you have a derived class with a method that should extend instead of replace the functionality defined in the method of the base class? Answer: Override the method in the derived class, and use the keyword base (Visual C#) or MyBase (Visual Basic) to call the method in the base class from the overriding method in the derived class.
3-14
Open the Animal class in the code view, and review the class definition. Recall how the base class was used in the previous demonstration. Pay attention to the Talk function, and how it often happens that an inherited class does not always have the same implementation for a method as the base class. In this case we want a different implementation for the Talk function. Note how the developer of the base class must allow the developer of the derived class to override the implementation of the method in question by specifying the keyword Overridable (Visual Basic) or virtual (Visual C#). Open the Lion class in the code view, and review the code. Notice how the Lion class inherits from the Animal class, and overrides the Talk function. Open Form1 in the code view, navigate to the btnPolymorphism_Click method, and review the code in the method. Press F5 to execute the application. Once the form has loaded, click the Polymorphism button. You should see three message boxes: the first with the base classs implementation of the Talk method which demonstrates inheritance, and the second with the derived classs implementation of the method which demonstrates overriding inheritance. The third messagebox demonstrates polymorphism by utilizing the base class and not referencing the derived classes. Notice the difference between inheritance code and polymorphic code and how polymorphism relies on inheritance. Also notice how the code below the comment //Polymorphic example (Visual C#) or Polymorphic example (Visual Basic) would not change if a different array of objects derived from Animal were passed to it. Stop the program application. Return to the code view of Form1, and place a breakpoint in the first executable line of code in the btnPolymorphism_Click method. Rerun the demonstration as in step 5, but this time step through the code, noticing when the code is in the Animal, Wolf or Lion classes. After the second message box, stop the application execution.
3. 4. 5.
6. 7.
8.
3-15
Additional Reading
Overrides and Overridable
override (C# Reference) Override Modifiers (Visual Basic Programming Guide) abstract (C# Reference)
3-16
You receive a warning when you try to override a method in the derived class.
You declare a variable V as the type of the base class, and you assign the variable V to hold an instance of the derived class. When you try to call one of the methods defined in the derived class, you receive an error. You declare two constructors in the base class, one that accepts a single parameter, and one that accepts no parameters. In the derived class, you create a new constructor that accepts a single parameter, but you do not create a constructor that accepts no parameters because you want to reuse the constructor defined in the base class. When you try to instantiate the derived class without passing parameters to the constructor, you receive an error.
Constructors are not inherited by derived classes. If you want to reuse the constructor method that accepts no parameters that is defined in the base class, you must create a constructor in the derived class that accepts no parameters, and use base (Visual C#) or MyBase (Visual Basic) to call the constructor in the base class from the constructor in the derived class.
3-17
orders have an OrderNumber, OrderDate, OrderTotal, and Status, and require a method called PayForOrder. Online orders also require a CustomerName and a ShipOrder method. How would you design the classes for this scenario? Answer: Use inheritance. Define Order as a base class, and put OrderNumber, OrderDate, OrderTotal, Status and the PayForOrder method in the base class. Create a OnlineOrder class that inherits from the Order class, and includes the extra members CustomerName and ShipOrder. 2. Scenario: In the above example should Orders be an abstract class? Answer: It depends. Based on the information provided, we do not need to add a RetailOrder class that is derived from the Order class, because there is no specialized functionality for the RetailOrder class. All the functionality required for retail orders is implemented in the base class, so you would create instances of the Order class directly for retail orders. If upon further investigation you discovered additional properties and methods that only apply to retail orders, then you would create a RetailOrder class, and the Order class would be declared as abstract because you would always create an instance of a RetailOrder or OnlineOrder, never an instance of the Order class directly. 3. Scenario: The book store decides to create a new type of order called Express orders. Express orders are only available online. They have two additional properties: DeliveryCharge, and PromisedDeliveryDate. The PayForOrder method must calculate the payment, and include the delivery charge. How would you implement this class? Answer: You create a new class called ExpressOrders that inherits the OnlineOrder class. You would also override the PayForOrder method in the ExpressOrders class to calculate the payment including the delivery charge.
3-18
Implementing Interfaces
4-1
Module 4
Implementing Interfaces
Contents:
Lesson 1: Introduction to Interfaces Lesson 2: Implementing an Interface Module Reviews and Takeaways Lab Review Questions and Answers 2 5 12 14
4-2
Lesson 1
Introduction to Interfaces
Contents:
Question and Answers 3
Implementing Interfaces
4-3
4-4
Answer: Answers will vary. An ICustomer interface that defines the ID and Name properties for customers would be useful to ensure that customer ID and customer names are stored consistently for retail and online customers. An IProduct interface would be useful to define functionality that must be supported for all product types. The Book and DVD classes would implement this interface, and it could also be implemented for any future products such as games and music CDs. An IOrder interface should be defined to define the common properties and methods for retail and Internet orders. This will make it easier to write reusable code that can record or update either Internet or retail orders.
Implementing Interfaces
4-5
Lesson 2
Implementing an Interface
Contents:
Question and Answers Detailed Demo Steps Additional Reading 6 8 11
4-6
IDisposable
Question: What types of resources are not released by the garbage collector, and should be released in a Dispose method? Answer: Unmanaged resources do not have their memory freed by the garbage collector. Examples of unmanaged resources include file handles, file streams, and resources created through APIs.
Implementing Interfaces
4-7
Question: Can a class implement part of an interface? Answer: No, the class must implement the entire interface. Question: Can an interface implement another interface? Answer: Yes, you can create an interface that implements another interface. This can be very useful because you define smaller interfaces to define standard functionality, and then create interfaces that build onto that standard. For example, you could have an IPayable interface that defines standard properties and methods for classes we can pay, such as an employee or contractor. You could then define an IPayableByDirectDeposit interface that implements the IPayable interface and additional properties required to support direct deposit to a bank account.
4-8
Open the Wolf class in the code view, and review the class definition. Uncomment the line that implements the IDisposable interface. a. b. c. Visual Basic: Make sure to press ENTER at the end of the definition line to ensure that the designer will add the code for the required methods. Visual C#: Right-click the IDisposable definition, and then click Implement Interface on the context menu. The comment line raises a new exception. Add the following line: System.Diagnostics.Debug.WriteLine(Dispose method);
3. 4. 5.
Open Form1 in the code view. Navigate to the btnSystemInterfaces_Click event handler. Uncomment the line that invokes the Dispose method. Add a breakpoint on that line. Open the Build menu and click Configuration Manager. In the Active Solution Configuration dropdown select Debug. Click Close. Press the F5 key to execute the application. Once the form loads, click System Interfaces. When the application hits the breakpoint, step through and review the code.
Implementing Interfaces
4-9
Open the IWolf interface in the code view, and review the definition. Open the Husky class in the code view, and review the code. Return to Form1 and find btnUserDefInterfaces_Click. Place a breakpoint in the first line of executable code, and then review the code. Press F5 to run the application. Wait for the form to load, and then click the User defined Interfaces button. When the breakpoint is hit, step through the code. Stop the program execution.
4-10
Open Form1 in the code view. At the bottom of the code, you will find the methods called LoadWolf (accepts a class as a parameter) and LoadIWolf (accepts an interface as a parameter). Navigate to the btnInterfacePoly_Click method, and review the code. Highlight the fact that the method that takes a class must take an instance of the defined class. The second method can take any class that implements the required interface. Place a breakpoint in the first line of executable code, and then press F5 to run the application. Click the Interface Polymorphism button, and step through the code. Notice the difference in the Talk() methods implementation. Stop the program execution.
4. 5. 6.
Implementing Interfaces
4-11
Additional Reading
Creating an Interface
Interfaces (C# Programming Guide) Interface Statement (Visual Basic) Interfaces in Visual Basic
IDisposable
IDisposable Interface Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework Implementing Finalize and Dispose to Clean Up Unmanaged Resources
4-12
After specifying that your class implements an interface, you receive compile errors when you attempt to build your application. You create a method and decide to use an interface type for your parameter to make your code more reusable. When you write code to call a method of the class you are passing into the method, you receive a compilation error. In a Visual Basic application, you have specified that an interface should be implemented in your class, and you have written the required methods and properties to implement the members of the interface. Yet you still receive compilation errors informing you that your class must implement the methods for the interface.
You have not specified the Implements keyword after the method declaration in your class, to link the method you created to the member of the interface it implements.
Implementing Interfaces
4-13
2.
You are defining an interface for a system boundary. In the first phase of the project, the system boundary must support a ReceiveCustomers method, which will retrieve a list of customers from a file to be imported into the application. In the second phase of the project, a SendOrders method is added to the system boundary, which will create a list of Orders and export them into a file. What methods should be included in the interface during the first phase of the project? Answer: Include both methods in the interface in the first phase of the project. The class that implements the interface can provide a method stub (that does nothing) for the first phase of the project. This prevents you from having to modify the interface in the second phase of the project.
3.
You are defining an interface for classes that implement logging. The interface is called ILoggable, and will define a method called LogMessage. LogMessage requires two parameters: message, and logDestination. There has been a lot of discussion about adding a logSeverity parameter to the method, but due to time constraints, the severity logic has been left out. How should you declare the logMessage method in the interface? Answer: Consider declaring overloaded methods for LogMessage in the interface: one which accepts the message and logDestination parameters, and a second which accepts the message, logDestination and logSeverity parameters. If later in the project the severity logic is added, the interface will not require any modifications.
4-14
5-1
Module 5
Designing Object-Oriented Structures
Contents:
Lesson 1: Establishing Classes from Business Requirements Lesson 2: Adding Inheritance to the Design Lesson 3: Adding Interfaces to the Design Lesson 4: Reviewing and Refining the Design Module Reviews and Takeaways Lab Review Questions and Answers 2 9 13 16 19 21
5-2
Lesson 1
5-3
Design Approaches
Question: What tools have you used in the past to document your design? Answer: Answers will vary based on experience.
5-4
Registration Properties: Student, Session, Course, Price, PaymentMethod, Status Methods: RegisterStudent, PayForRegistration, CancelRegistration
Student
5-5
Question: What candidate classes, properties, and methods can you identify from this business scenario? Answer: Answers will vary, but possible candidate classes include: Course, Session, Registration, Student, and Instructor. Methods and properties will also vary, but possible properties and methods for the candidate classes are listed above. You may identify additional properties and methods based on assumptions that the business requires more than the requirements listed in the short scenario described in the student manual.
5-6
[Visual C#]
public String Name { get; set; } public boolean Update() { return false; }
[Visual Basic]
Public Property Name() As String Get End Get Set(ByVal value As String) End Set End Property Public Function Update() As Boolean Return False End Function
3.
5-7
5-8
Additional Reading
Class Diagrams
Design Approaches
UML Notation Microsoft Office Visio 2007 Product Overview The Nordic Object/Relational Database Design
5-9
Lesson 2
5-10
5-11
Possible methods and properties for these base and derived classes include: Session Properties: Course, StartDate, Status, Instructor Methods: ScheduleSession, ConfirmSession, CancelSession, AssignInstructor
5-12
Question: If the company offers discounts on the price depending on the number of students attending a dedicated course, and also offers a discount on public course sessions in the summer to increase attendance, where should discount be stored? Answer: The discounts are calculated differently for dedicated courses, so the discount should be stored in the derived class DedicatedSession. This way, you can store the discount for more than five students, and the discount for more than ten students. You should also store a discount in the derived class PublicSession. You may want to ask the company if the summer discounts apply to the dedicated sessions as well, in which case discount should be stored in the base class Session, instead of in the Public Session class. Question: Where should the method ScheduleSession be stored? Answer: You may need more information from the business to find out where to store ScheduleSession. Are there different business rules that must be followed when scheduling a public session or a dedicated session? They may be stored in different database tables. Find out if instructors are scheduled immediately for dedicated sessions, while public sessions only have instructors scheduled if they have three or more students registered. If the business rules are the same for both types of sessions, then the method should be listed in the Session class. .If the rules are completely different for both types of sessions, then the method should be listed in the derived classes, PublicSession and DedicatedSession. If the method has some common functionality and extra steps required for public and dedicated sessions, then you should list the method in both the base and derived classes, and when you implement the method in the derived class, you will call the method in the base class. Question: Are all the properties and classes in the proper place? Answer: Answers will vary based on the solution designed. Properties should be in the base class if they apply to the base class and all derived classes. Properties should be in the derived classes where they are required, if they do not apply to the base class and all derived classes. Question: Is inheritance used properly? Answer: Answers will vary based on the solution designed. Inheritance should be used when there are classes with similar common functionality.
5-13
Lesson 3
5-14
5-15
Answer: Answers may vary, but the Course property of the Session class that keeps track of what course a session scheduled could be of type ISchedulableEventInterface. This would allow the Session class to track sessions for seminars and workshops, as well as courses. Question: Will the interface be able to handle updates? Answer: Answers will vary. We are already preparing for updates by designing the interface to handle workshops and seminars.
5-16
Lesson 4
5-17
5-18
business layer classes would instantiate the data layer classes, and execute the methods to access the database as needed. One common functionality between applications consideration is error logging. You may want to define an error handling class that will handle and log any errors that are raised by the classes during execution. This class could be reused in other .NET applications.
5-19
You are missing a class. You should add a ticket class that would store the price paid by a particular passenger for a particular flight. When you have a property that could have multiple values for an instance of a class, you may be missing a class.
You should add a new class called Orders. The Orders class contains a property called Orders that is a collection of instances of the Order class. You can associate the Customer class with the Orders class so that you can see all the orders placed by a particular customer.
You are designing your classes, and you are having trouble identifying the methods to implement in the classes. It seems like every class just has three methods called Add, Update, and Delete.
Are you designing a data layer class that will be sending Insert, Update, and Delete statements to the database? If so, the methods you have defined are reasonable. If you are defining business layer classes, the method names should reflect the business process or task being performed. For example, a cancelTicket method in a ticket class is updating the status property of a ticket class, but the name UpdateTicket does not indicate the business function being performed as clearly as cancelTicket.
5-20
Tools
Tool Use for Creating class diagrams and code generation Creating class diagrams and code generation Where to find it
http://office.microsoft.com/enus/visio/default.aspx
5-21
6-1
Module 6
Delegates, Events and Exceptions
Contents:
Lesson 1: Introduction to Delegates Lesson 2: Implementing Delegates Lesson 3: Introduction to Events Lesson 4: Implementing Events Lesson 5: Introducing Exceptions Lesson 6: Implementing Exceptions Module Reviews and Takeaways Lab Review Questions and Answers 2 5 11 13 18 20 26 28
6-2
Lesson 1
Introduction to Delegates
Contents:
Question and Answers Additional Reading 3 4
6-3
6-4
Additional Reading
Introduction to Delegates
Delegates (C# Programming Guide) Delegates in Visual Basic
6-5
Lesson 2
Implementing Delegates
Contents:
Question and Answers Detailed Demo Steps Additional Reading 6 8 10
6-6
Delegates
Question: What changes would you need to make to the button1_Click method if more delegate callbacks were registered? Answer: No changes are needed. Question: What would the button1_Click method look like if delegates were not used? Answer: Most likely, the button1_Click method would directly call each method. Therefore, as the method list changed, the button1_Click method would have to be updated as well. To dynamically register/unregister the methods from being called, each method call would likely be wrapped within if statements. 1. 2. 3. 4. Run the project in debug mode. Check Register Class 1 Delegate and step through the code. Check Register Class 2 Delegate and step through the code. Click Invoke Delegate, and step through the code.
Question: What is the advantage of using a multicast delegate? Answer: A multicast delegate has the advantage of separating the delegate registration/deregistration of multiple methods away from the code that calls the delegate.
6-7
Question: In the Method Selection part of the demonstration, what is the difference from using a delegate to help determine which method to invoke versus using logic statements to determine which method to invoke? Answer: By using a delegate, the code that invokes the delegate will not require updating if the list of methods changes.
6-8
Within Form1.cs for Visual C# or Form1.vb for Visual Basic, find the delegate type declaration for DelegateNotify. Examine the delegate type declaration, and notice how it matches the signature of the methods to invoke. Examine the instance declaration NotifyList of the delegate DelegateNotify type on the following line. Examine the code within the checkBox1_CheckedChanged method. Notice how the method registers C1.SendMessage to the delegate. Move to the checkBox2_CheckedChanged method. Examine how the method registers c2.NotHelloWorld. Notice how the methods have no parameters, and the methods being called in c1 and c2 do not have to be named the same, but need the same parameter list. Also notice how these methods need to match the delegate type DelegateNotify declared above. Show the code within the button1_Click event handler method. Examine how this method is unaware of what methods are being called, or the number of methods being called. Remember that we should check that there is at least one method to call before invoking the delegate instance. Open class1.cs and show the SendMessage method. Open class2.cs and show the NotHelloWorld method.
4. 5. 6.
7.
8. 9.
10. In Form1.cs for Visual C# or Form1.vb for Visual Basic, set a breakpoint on the following methods: button1_Click checkBox1_CheckedChanged checkBox2_CheckedChanged
6-9
5.
Examine the code within the doProcess method. Notice how the parameter is a delegate instance called delProcessList, and is of type ProcessList. Notice how the method simply invokes the delegate instance delProcessList. Examine the code within the button2_Click method. Notice how the button2_Click method passes new delegate created from the SortIt method to the doProcess method. Notice how the button3_Click method does the same thing as the button2_Click method, but passes the ReverseIt method instead. Run the project. Click on the Sort List and String Reverse buttons. Notice how any method that matches this signature could be passed to doProcess, and manipulate the list without affecting the code within the doProcess method.
6. 7. 8. 9.
6-10
Additional Reading
Defining a Delegate Type
Using Delegates (C# Programming Guide) A Primer on Creating Type-Safe References to Methods in Visual Basic .NET
Instantiating a Delegate
How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide) Delegates and the AddressOf Operator
6-11
Lesson 3
Introduction to Events
Contents:
Question and Answers 12
6-12
6-13
Lesson 4
Implementing Events
Contents:
Question and Answers Detailed Demo Steps Additional Reading 14 15 17
6-14
Events
Question: Why would you want to define your own events within your classes? Answer: By defining your own events within your classes, you can better represent the existing business structures. Also, the classes will better encapsulate their own functionality. For example, an order object that raises its own OrderChanged event requires less logic in other parts of an application to determine if the order has changed. Question: Should custom events use the same parameters as system-defined events? Answer: Custom events are not required to use the same parameters as system-defined events. However, many developers will use the same parameters to provide some consistency in how events are used within their application.
6-15
Build the project. Open Form1.cs (Visual C#) or Form1.vb (Visual Basic) from the Solution Explorer. Examine the form. Add a button to the bottom, right hand corner of the form with a text property of Modify OrderItem. Double-click the button. Examine the parameters of the button1_Click method. In the button1_Click method, add code to display the text Modify OrderItem has been clicked in a message box. Examine how the event handler is registered. Note: Visual C# only: Press CTRL+F, and then type this.button1.Click. Change Look in: to Entire Solution, and then click Find Next. Point out to students how double-clicking the button added this code automatically.
9.
10. Click Modify OrderItem. Examine how the event handler code was called.
2. 3. 4. 5.
6-16
Near the top of the Order class below //TODO add event declarations, add an event named OrderChanged. For Visual C#, name the delegate OrderChangedEventDelegate. Add Code to Raise an Event In the orderItem_PricingChanged method, raise the event. For Visual C#, remember to check that OrderChanged is not empty.
2. 3. 4.
6-17
Additional Reading
Creating System Event Handlers
EventHandler Delegate WithEvents and the Handles Clause
Raising an Event
6-18
Lesson 5
Introducing Exceptions
Contents:
Question and Answers 19
6-19
6-20
Lesson 6
Implementing Exceptions
Contents:
Question and Answers Detailed Demo Steps Additional Reading 21 23 25
6-21
Throwing Exceptions
Question: How can you handle an exception in your code, and still pass the exception to the calling class? Answer: In your catch statement, rethrow the exception. Question: What will happen in the application after the ArgumentException in the in the example is thrown? Answer: If this code is within a try block, execution will jump to the catch block to handle the exception. If this code is not in a try block, then the GetCourse method would exit, and execution would jump to the exception handling of the caller.
Exceptions
Question: What possible things can we do to better handle the exception? Answer: We could record the error within a log file or database for analysis by administrators. We could also attempt to resolve the issue, if possible. Question: Should we use an event (such as DataErrorFixed) or should we use an exception to notify the caller that the value of UnitPriceDiscount was invalid, and has been changed to a valid value? Answer: Using an event handler would incur less overhead, and provide a notification to any event listener that the value has changed. Since the invalid value is easily rectified, there is little value in raising an exception. Unhandled exceptions will also be passed to the user interface. Using an exception will also incur the overhead of creating an exception object, which can be expensive when creating performance code. Question: What is the benefit to creating custom exception classes?
6-22
Answer: By using a custom exception class, code that catches the exception can better respond to a specific exception type. The custom exception class can more easily implement code within the exception class, such as logging exception information.
6-23
3. 4. 5. 6.
6-24
3. 4.
4.
Note: Notice how the code restricts the UnitPriceDiscount from being set to anything over 1 (100%).
5. 6.
Run the project. Change the value of the UnitPriceDiscount to 1.2. Notice the effect of the change.
6-25
Additional Reading
Handling Exceptions
try-catch (C# Reference) try-finally (C# Reference) TryCatchFinally Statement (Visual Basic)
Exception Class
Throwing Exceptions
Creating and Throwing Exceptions (C# Programming Guide) How to: Throw an Exception in Visual Basic Exception.InnerException Property
6-26
There may not be an event handler method defined for the event, or you may have created an event handler method and not associated it with the event.
Rethrow the exception within the catch section in your class, or throw a new exception within the catch section in your class. When you handle an exception, the exception is not passed up to the calling class.
6-27
Answer: Write code in the UpdateBalance method to check how many records were updated by the Update statement sent to the database. If zero records are updated, throw a new exception UnknownAccount, and let the BillPayment method in the BankAccount class handle the exception. 2. You have a BankAccount class with a Withdraw method. Users are allowed to overdraw from their accounts by up to five hundred dollars, however whenever an account is overdrawn you want to notify the user that their account is overdrawn and let them know by how much their account is overdrawn. How can you implement this in your code? Answer: In the BankAccount class, define an event called Overdrawn with a parameter AmountOverdrawn. In the Withdraw method, if the amount withdrawn exceeds the account balance, raise the AmountOverdrawn event and pass the amount overdrawn. In your user interface class, create an event handler method to display a message to the user when the event is raised.
6-28
Lab 6B
1. Could the exception within the lab be handled in a better way? Answer: Yes, the error could have been logged. Sending raw exception messages to the user interface is never good practice. If corrective action could have been applied, it should have. However, the example in the lab allows for little corrective action to be taken. 2. What is the benefit of handling an exception with a custom exception class? Answer: By using a custom exception class, code can be added later to the exception class to implement a custom logging solution. As well, having a custom exception class to be thrown helps to identify the type of error within the catch, which allows for more specific corrective action to be taken during the catch. 3. What is the difference between using an event as a notification model versus using an exception? Answer: Using an event can offer a multicast notification model, whereas exceptions cannot. Exceptions usually incur more overhead because of the additional exception object creation. Exceptions are the expected method of handling errors and follow a standardized approach, which helps with code consistency.
7-1
Module 7
Designing Object Collaboration
Contents:
Lesson 1: Introduction to Class Interactions Lesson 2: Adding Interactions to a Design Lesson 3: Evaluating the Design Lesson 4: Introduction to Patterns Module Reviews and Takeaways Lab Review Questions and Answers 2 4 9 12 15 17
7-2
Lesson 1
7-3
7-4
Lesson 2
7-5
7-6
7-7
Question: What method will detect the exception? Answer: The AddRegistration method of the Session class, because it knows the maximum number of registrations, and has the registrations collection of all registrations for the session. Question: Which class should handle the exception? Answer: Answers will vary, but the user interface must receive the exception, because the user interface will need to display a message to the user, informing them the session is full. Question: Why does the RegisterSession rethrow the SessionFull exception? Answer: Because we want the student who is using the application to know that the session is full. By rethrowing the exception, we allow the user interface class to know that an exception has occurred and display an error message to the user.
7-8
Additional Reading
Adding Events to a Design
Event Design
7-9
Lesson 3
7-10
7-11
would change and other classes would be affected. However we are not passing a large number of properties so there are minimal dependencies between the classes.
7-12
Lesson 4
Introduction to Patterns
Contents:
Question and Answers Additional Reading 13 14
7-13
7-14
Additional Reading
Defining Patterns
Using Patterns to Define a Software Solution patterns & practices
Common Patterns
Exploring the Factory Design Pattern Exploring the Singleton Design Pattern Design Patterns Model View Presenter Model View Controller
7-15
Events are asynchronous. They fire event handlers, but you do not control when the event handlers fire. If your code continues execution and performs an action such as sending an e-mail, there is no guarantee that the event handler will have finished execution before your code sends the e-mail. For this situation, events are not a good choice for the class interaction, because we cannot guarantee the event handler has sent the message text before the e-mail is sent.
Pass a session object as a parameter, instead of passing parameters for individual session properties. That way, all the session properties are available to the method.
7-16
Tools
Tool Office Visio Use for Drawing sequence diagrams Where to find it
http://office.microsoft.com/enus/visio/default.aspx
7-17
8-1
Module 8
Deploying Components and Class Libraries
Contents:
Lesson 1: Introduction to Components and Class Libraries Lesson 2: Deploying a Component/Class Library Lesson 3: Best Practices for Deploying a Component/Class Library Module Reviews and Takeaways Lab Review Questions and Answers 2 5 8 16 19
8-2
Lesson 1
8-3
8-4
Additional Reading
Factors for Creating Deployable Units of Software
Requesting Permissions Permissions View Tool (Permview.exe)
8-5
Lesson 2
8-6
Deploying an Assembly
Question: When should you deploy to the /bin directory instead of the global assembly cache? Answer: When the assembly is only used by a single application. However, there are advantages to storing an assembly in the global assembly cache even if it is only used by a single application. You will learn the benefits of using the global assembly cache in the next topic.
8-7
Open Form1 in the code view, and review the code for the Upper function and the btnOk_Click method. Press the F5 key to run the application. Type aaa into the text box, and then click OK. You should see a message box with AAA returned. Add a new project of type Class Library. Ensure you are using the same language as the current application. Enter MyUtils in the name box, leave the location as is, and then click OK. Rename Class1.cs or Class1.vb to Utils.cs or Utils.vb. Create a public function called Upper that is similar to the one in Form1, but add to it code that will display assembly information, such as the assembly name and version, and whether the assembly is in the global assembly cache or not. Your code should resemble the following:
5.
[Visual Basic]
Public Function Upper(ByVal str As String) As String Dim Asm As System.Reflection.Assembly = _ System.Reflection.Assembly.GetExecutingAssembly Return str.ToUpper() & " From GAC : " _ & Asm.GlobalAssemblyCache.ToString() & ", Name " & Asm.FullName End Function
[Visual C#]
public string Upper(string str) { System.Reflection.Assembly Asm = System.Reflection.Assembly.GetExecutingAssembly(); return str.ToUpper() + " From GAC : " + Asm.GlobalAssemblyCache.ToString() + ", Name " + Asm.FullName; }
6. 7.
In the Module08Demo project, add a reference to the MyUtils project. Return to the code in Form1. Delete or comment out the local Upper function, and modify the code in the click event to use the Upper method in the class library. Your code should resemble the following:
[Visual Basic]
Dim AUtil As New MyUtils.Utils MessageBox.Show(AUtil.Upper(txtString.Text))
8-8
[Visual C#]
MyUtils.Utils AUtils = new MyUtils.Utils(); MessageBox.Show(AUtils.Upper(txtString.Text));
8.
Save the projects, and build the solution. Make sure the build is successful, and then press F5 to execute the application. Type aaa into the text box, and then click OK. You should see a message box the result. Note that the assembly is not in the global assembly cache. Stop the project execution.
9.
8-9
Select the MyUtils project, right-click the project, and then select Properties. Once the Properties window opens, select the Signing tab. Sign the assembly by creating a key file with the name of MyUtils. Secure the file with a password of Pa$$w0rd. Ensure the build configuration is set to release, and build the project. Several methods exist to add an assembly to the global assembly cache. You are going to use a setup project. Add a new project of type Setup. In the Name box, change the name to MyUtils Setup. Ensure the setup project is selected, and on the right-click the File System on Target Computer node. Click Add Special Folder, and then click Global Assembly Cache Folder. Once the global assembly cache folder has been created, right-click on the folder, and then click Add, and then click Assembly. Select the Browse tab, and then browse to the Release folder of the MyUtils project. Select the MyUtils.dll file, and then click OK. Save and build the setup project. Ensure the build is successful. Right-click the MyUtils Setup project, and select Install. Follow the prompts of the installation wizard, and click next on each screen to install the assembly. Once the installation is successful, ensure Module08Demo is set as the startup project, and then press F5 to run the application. Type aaa into the text box, and then click OK. The message displayed will now have the value of true to indicate the assembly in being run from the global assembly cache. Stop the execution of the project.
6.
7.
8.
9.
10. Click Start, point to Administrative Tools, then open the Microsoft .NET Framework 2.0 Configuration tool. Click Manage the Assembly Cache, and then click View List of Assemblies in the Assembly Cache. Find the MyUtils assembly. Right-click the assembly, and select Properties. View the Properties of the Assembly. Click Cancel to close the window.
8-10
Make a minor change to the code in the assembly by following the steps: a. b. Open the Utils class in the MyUtils Project in the code view. In the line that returns the value, modify the code so that three exclamation marks are added to the string.
3.
Right-click the MyUtils project, and then select Properties. Click the Application tab, and then click the Assembly Information button. Change the Assembly and File version to 2.0.0.0, and then click OK. Close the property pages. Build the MyUtils project, and ensure that the build is successful. Press F5 to execute the project, type aaa into the text box, and then click OK. The message box displayed does not have the exclamation marks, and it indicates that it is loaded from the global assembly cache. You are going to now add a second version of the assembly to the GAC using the Microsoft .NET Framework 2.0 configuration tool. a. b. Open the Microsoft .NET Framework 2.0 Configuration tool, click Manage the Assembly Cache, and then Add an assembly to the Assembly Cache. Navigate to the release folder of the MyUtils project. Select the MyUtils.dll file, and then click Open. You should now have two versions of the assembly in the cache (version 1.0.0.0. and 2.0.0.0).
4.
5.
6. 7.
Return to Visual Studio 2008 and press F5 to execute the application. Type aaa into the text box, and then click OK. You should see a message indicating that the assembly was loaded from the global assembly cache, is version 2.0.0.0, and should have exclamation marks at the end of the message. However, you would like the application to continue using version 1.0.0.0 of the assembly. To achieve this, you need to add a binding redirection instruction in an app.config file. a. b. Right-click Module08Demo, select Add, and then click New Item. Select Application Configuration File, and the click Add. Once the app.config file has been added and loaded, type the following XML into the configuration file just above the bottom </configuration> tag:
8.
8-11
<runtime> <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1"> <dependentAssembly> <assemblyIdentity name="MyUtils" publicKeyToken="" culture="neutral" /> <!-- Assembly versions can be redirected in application, publisher policy, or machine configuration files. Redirection from younger to older version in our case --> <bindingRedirect oldVersion="2.0.0.0" newVersion="1.0.0.0" /> </dependentAssembly> </assemblyBinding> </runtime>
9.
Open the Microsoft .NET Framework 2.0 configuration tool. Click Manage the Assembly Cache, and then click View List of Assemblies in the Assembly Cache.
10. Find the MyUtils assembly. Since the public key is the same for version 1.0.0.0 and 2.0.0.0, either version of the MyUtils assembly can be used. Right-click the assembly, and then select Properties. Copy the Public Key Token value, and then click Cancel. 11. Return to Visual Studio 2008, and paste the Public key token value in the app.config file as the value for publicKeyToken. Note that in your example you are rerouting the request from a new assembly version to an older assembly version. Save the app.config file. 12. Build Module08Demo and ensure the build is successful. 13. Press F5 to start the execution of the application. Type aaa into the text box, and then click OK. You should see a message that displays version 1.0.0.0 of the assembly. 14. Stop the program execution.
8-12
Additional Reading
What Is an Assembly?
Deploying an Assembly
Deploying Assemblies
8-13
Lesson 3
8-14
Verifying Results
Question: What issues have you encountered in the past when deploying updates? Answer: Answers will vary based on experience, but a common issue is updating code that is shared, deploying it, and accidentally causing errors in the application that shares the assembly.
8-15
Additional Reading
Best Practices: Deploying Components/Class Libraries
8-16
Additional reading
The assembly containing the class that reads the file requires the FileIOPermission, and that permission has not been granted to the assembly. If you do not specify the permissions required for the assembly, the assembly will execute, but an exception will be raised if you attempt to perform an operation for which you have not been granted the necessary permissions.
Your assembly has requested the FileIOPermission as a minimum permission to ensure it will be able to read the XML file, but the assembly does not have the minimum
8-17
development. When you deploy the application to production, the application works as expected, but when you try to execute any code in the assembly that reads the file, you receive an error message informing you that you do not have the required minimum permissions. What is the most likely cause?
permissions. When you specify the minimum permissions required in an assembly, the .NET Framework will verify the assembly has the necessary permissions when it is loaded. You will not be able to access any functionality in the assembly until the minimum permissions have been granted to the assembly. This check helps you catch missing permissions without retesting your entire application.
Tools
Tool Use for Where to find it .NET Framework 2.0 Software Development Kit .NET Framework 2.0 Software Development Kit .NET Framework 2.0 Software Development Kit
GacUtil.exe
Installing strong-named assemblies to the global assembly cache Global assembly cache viewer that allows you to view and add assemblies in the global assembly cache A MMC Snap-in that allows you to manage and configure assemblies in the global assembly cache.
8-18
Generates a file with an assembly manifest, used to build a publisher policy assembly file to redirect an assembly for an application
8-19
R-1
Resources
Contents:
Microsoft Learning Technet and MSDN Content Communities 2 3 6
R-2
Microsoft Learning
This section describes various Microsoft Learning programs and offerings. Microsoft Learning You can search for the skills assessment options available through Microsoft, also describes the training options available through Microsoft face-to-face or self-paced. Microsoft Certification Program Details how to become a Microsoft Certified Professional, Microsoft Certified Database Administrators, and more. Microsoft Learning Support To provide comments or feedback about the course, send e-mail to support@mscourseware.com. To ask about the Microsoft Certification Program (MCP), send e-mail to mcphelp@microsoft.com
R-3
MSDN
Structures and Classes Extending Metadata Using Attributes Auto-Implemented Properties (C# Programming Guide) Using Properties (C# Programming Guide) Adding Properties to Your Class Event Design Patterns & practices Visual Studio 2005 Class Designer Object Browser Test Bench Drill Into .NET Framework Internals to See How the CLR Creates Runtime Objects Project Templates in Visual Studio Web Application Projects Overview Comparing Web Site Projects and Web Application Projects Value Types in the Common Type System NET Type Fundamentals System.Collections.Generic Namespace IConvertible Interface Casting and Type Conversions (C# Programming Guide) How to: Convert a string to an int (C# Programming Guide) Converting Types XML Documentation Comments (C# Programming Guide) What's new in Visual Studio 2008 Intellisense Features XML Comments Let You Build Documentation Directly From Your Visual Studio .NET Source Files (C#) Visual Basic Language Concepts Documenting Your Code with XML (Visual Basic) Garbage Collection: Automatic Memory Management in the Microsoft .Net Framework Garbage Collection Operator Overloading Usage Guidelines
R-4
Operator Overloading Tutorial Inheritance (C# Programming Guide) Inheritance Basics (Visual Basic Programming Guide) Abstract MustInherit Base First statement of this Sub New must be a call to MyBase.New or MyClass.New (More Than One Accessible Constructor Without Parameters) Hiding through Inheritance Override Modifiers (Visual Basic Programming Guide) abstract (C# Reference) override (C# Reference) Interfaces (C# Programming Guide) Interface Statement (Visual Basic Programming Guide) Interfaces in Visual Basic (Visual Basic Programming Guide) IDisposable Interface Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework Implements Statement (Visual Basic Programming Guide) How to: Explicitly Implement Interface Members (C# Programming Guide) Inheritance and Interfaces Qualifying .NET Types for Interoperation Visual Studio 2005 Class Designer UML Notation Microsoft Office Visio 2007 Product Overview The Nordic Object-Relational Design (an ORM example) Delegates (C#) Delegates in Visual Basic Using Delegates (C# Programming Guide) A Primer on Creating Type-Safe References to Methods in Visual Basic .NET How to: Declare, Instantiate and Use a Delegate (C# Programming Guide) Delegates and the AddressOf Operator (Visual Basic Programming Guide) Asynchronous Programming Using Delegates Asynchronous Programming Overview EventHandler Delegate
R-5
WithEvents and the Handles Clause (Visual Basic Programming Guide) Events Tutorial (C# Programmer’s Reference) How to: Add Events to a Class (Visual Basic Programming Guide) Raising an Event How to: Connect Event Handler Methods to Events AddHandler and RemoveHandler try-catch (C# Reference) try-finally (C# Reference) TryCatchFinally Statement(Visual Basic) Exception Class Creating and Throwing Exceptions (C# Programming Guide) How to: Throw an Exception (Visual Basic Application Development) Exception.InnerException Property Using Patterns to Define a Software Solution Exploring the Factory Design Pattern Exploring the Singleton Design Pattern Design Patterns Model View Presenter Model View Controller Requesting Permissions Permissions View Tool MSF Process Model Overview Manifest Generation and Editing Tool (Mage.exe) Deploying Assemblies Global Assembly Cache How to: Install an Assembly Into the Global Assembly Cache Global Assembly Cache Tool (Gacutil.exe) Assembly Cache Viewer (Shfusion.dll) Redirecting Assembly Versions How to: Create a Publisher Policy Strong Name Tool Understanding Service-Oriented Architecture
R-6
Communities
There is no content from Communities in this course.
R-7
Courseware Feedback
Send all courseware feedback to support@mscourseware.com. We truly appreciate your time and effort. We review every e-mail received and forward the information on to the appropriate team. Unfortunately, because of volume, we are unable to provide a response but we may use your feedback to improve your future experience with Microsoft Learning products.
Reporting Errors
When providing feedback, include the training product name and number in the subject line of your email. When you provide comments or report bugs, please include the following: Document or CD part number Page number or location Complete description of the error or suggested change
Please provide any details that are necessary to help us verify the issue.
Important All errors and suggestions are evaluated, but only those that are validated are added to the product Knowledge Base article.