9.13. Time Class Case Study: Creating Class Libraries We have seen that classes from preexisting libraries, such as .NET's Framework Class Library (FCL), can be imported into Visual Basic applications. Each class in the FCL belongs to a namespace that contains a group of related classes. Class libraries and namespaces facilitate software reuse by enabling applications to add classes from other namespaces (as we have done in most examples). This section demonstrates how to create your own class libraries for reuse. Making a Class Reusable Before a class can be imported into multiple applications, it must be placed in an assembly to make it reusable. The steps for creating an assembly are as follows: Create a Class Library project. Add the reusable class(es) to the project. [Note: You can also create reusable classes from scratch.] Ensure that each reusable class is declared Publiconly Public classes can be imported for use in other projects; non-Public classes are typically placed in a library to support the Public reusable classes in that library. Compile the project to create the assembly that contains the reusable class(es). In an application that requires the class library, add a reference to the class library. Then specify an Imports statement for the class library and use its class(es) in your application. Next, we present the five steps in detail. | | Step 1. | Creating a Class Library Project
In this example, we'd like to place class Time of Fig. 9.1 into a class library to make it a reusable class. To create a class library in Visual Basic 2005 Express, select File > New Project... and choose Class Library from the list of templates, as shown in Fig. 9.18. Name your project TimeLibrary, then click OK.
Figure 9.18. Creating a Class Library Project. When you create a Class Library project, Visual Basic automatically includes the file Class1.vb in the project. You can modify the Public class in this file to create a reusable class. However, we'll be using the file from the Time class in Fig. 9.1, so you can select Class1.vb in the Solution Explorer and press Delete to remove it from the project.
| Step 2. | Adding Class Time to the Project
Next, you must add the file that contains class Time to the project. Right click TimeLibrary in the Solution Explorer. In the menu that appears, select Add > Existing Item... to display the Add Existing Item dialog box. Locate the Time.vb file from Fig. 9.1, select it and click the Add button to add the file to this Class Library project. [Note: We assume that you downloaded the book's examples and placed them on your C:\ drive. If so, the file is located in the directory C:\examples\ch09\Fig09_01-02\TimeTest\.]
| | | Step 3. | Adding Class Time to the Project
Recall that only Public classes can be imported for use in other projects. Thus, you must add the Public access modifier to class Time to make it reusable. The new version of class Time is shown in Fig. 9.19. Notice that line 3 now contains Public.
Figure 9.19. Creating reusable class Time. 1 ' Fig. 9.19: Time.vb 2 ' Represents time to clients in 12-hour and 24-hour clock formats. 3 Public Class Time 4 Inherits Object ' if not specified, compiler includes it implicitly 5 6 ' declare Integer instance variables for the hour, minute and second 7 Private hourValue As Integer ' 0 - 23 8 Private minuteValue As Integer ' 0 - 59 9 Private secondValue As Integer ' 0 - 59 10 11 ' Time constructor initializes instance variables 12 ' when a Time object is created 13 Public Sub New() 14 SetTime(12, 0, 0) ' initialize hour to noon; minute, second to 0 15 End Sub ' New 16 17 ' set a new time value using universal time, check validity of the 18 ' data, set invalid hour to noon, set invalid minute, second to zero 19 Public Sub SetTime(ByVal hh As Integer, _ 20 ByVal mm As Integer, ByVal ss As Integer) 21 Hour = hh ' set hourValue using Hour property 22 Minute = mm ' set minuteValue using Minute property 23 Second = ss ' set secondValue using Second property 24 End Sub ' SetTime 25 26 ' property Hour 27 Public Property Hour() As Integer 28 Get ' return hourValue 29 Return hourValue 30 End Get 31 32 Set(ByVal value As Integer) ' set hourValue 33 If (value >= 0 AndAlso value < 24) Then ' in range 0-23 34 hourValue = value ' value is valid 35 Else ' value is invalid 36 hourValue = 12 ' set to default of noon 37 End If 38 End Set 39 End Property ' Hour 40 41 ' property Minute 42 Public Property Minute() As Integer 43 Get ' return minuteValue 44 Return minuteValue 45 End Get 46 47 Set(ByVal value As Integer) ' set minuteValue 48 If (value >= 0 AndAlso value < 60) Then ' in range 0-59 49 minuteValue = value ' value is valid 50 Else ' value is invalid 51 minuteValue = 0 ' set to default of 0 52 End If 53 End Set 54 End Property ' Minute 55 56 ' property Second 57 Public Property Second() As Integer 58 Get ' return secondValue 59 Return secondValue 60 End Get 61 62 Set(ByVal value As Integer) ' set secondValue 63 If (value >= 0 AndAlso value < 60) Then ' in range 0-59 64 secondValue = value ' value is valid 65 Else ' value is invalid 66 secondValue = 0 ' set to default of 0 67 End If 68 End Set 69 End Property ' Second 70 71 ' convert Time to a String in universal-time (24-hour clock) format 72 Public Function ToUniversalString() As String 73 Return String.Format("{0}:{1:D2}:{2:D2}", Hour, Minute, Second) 74 End Function ' ToUniversalString 75 76 ' convert Time to a String in standard-time (12-hour clock) format 77 Public Overrides Function ToString() As String 78 Dim suffix As String ' AM or PM suffix 79 Dim standardHour As Integer ' a standard hour in the range 1-12 80 81 ' determine whether the 12-hour clock suffix should be AM or PM 82 If Hour < 12 Then 83 suffix = "AM" ' note space preceding AM 84 Else 85 suffix = "PM" ' note space preceding PM 86 End If 87 88 ' convert hour from universal-time format to standard-time format 89 If (Hour = 12 OrElse Hour = 0) Then 90 standardHour = 12 91 Else 92 standardHour = Hour Mod 12 ' 1 through 11, AM or PM 93 End If 94 95 Return String.Format("{0}:{1:D2}:{2:D2} {3}", _ 96 standardHour, Minute, Second, suffix) 97 End Function ' ToString 98 End Class ' Time | | Step 4. | Building the TimeLibrary
To create the assembly containing the reusable class, select Build > Build TimeLibrary. When you build a Class Library project, the compiler creates a .dll file, known as a dynamic link librarya type of assembly that you can reference from other applications. This assembly is located in the project's bin\Release directory. By default, the name of the file is the class library's name followed by the .dll extensionTimeLibrary.dll in this example. The assembly file contains the reusable class Time, which can now be imported into other projects. Save your project and remember where you saved it on your system, so you can locate the TimeLibrary.dll file in the next step. Note that class libraries are not executable, so if you attempt to execute the class library by selecting Debug > Start, you'll receive an error message.
| | | Step 5. | Create an Application, Add a Reference to the Class Library's Assembly and Import the Library's Namespace
Once the class is compiled and stored in an assembly, it can be imported into a program for reuse. Module TimeLibraryTest (Fig. 9.20) uses class Time from the assembly TimeLibrary.dll to create a Time object, set its time and display the time.
Figure 9.20. Module TimeLibraryTest references TimeLibrary.dll. 1 ' Fig. 9.20: TimeLibraryTest.vb 2 ' Demonstrating class Time in TimeLibrary. 3 Imports TimeLibrary ' import namespace TimeLibrary 4 5 Module TimeLibraryTest 6 Sub Main() 7 Dim time As New Time() ' call Time constructor 8 9 Console.WriteLine("The initial universal time is: " & _ 10 time.ToUniversalString() & vbCrLf & _ 11 "The initial standard time is: " & time.ToString()) 12 13 time.SetTime(13, 27, 6) ' set time with valid settings 14 Console.WriteLine(vbCrLf & "Universal time after setTime is: " & _ 15 time.ToUniversalString() & vbCrLf & _ 16 "Standard time after setTime is: " & time.ToString()) 17 18 time.SetTime(99, 99, 99) ' set time with invalid settings 19 Console.WriteLine(vbCrLf & _ 20 "After attempting invalid settings: " & vbCrLf & _ 21 "Universal time: " & time.ToUniversalString() & _ 22 vbCrLf & "Standard time: " & time.ToString()) 23 End Sub ' Main 24 End Module ' TimeLibraryTest The initial universal time is: 12:00:00 The initial standard time is: 12:00:00 PM Universal time after setTime is: 13:27:06 Standard time after setTime is: 1:27:06 PM After attempting invalid settings: Universal time: 12:00:00 Standard time: 12:00:00 PM |
| When you create a Class Library project, the classes in that library are automatically placed in a namespace that has the same name as the library itself. Thus, class Time is located in namespace TimeLibrarypart of the assembly TimeLibrary.dll. Before you can use the classes in the namespace TimeLibrary, you must reference its assembly. Select Project > Add Reference..... The Add Reference dialog that appears contains a list of class libraries from the .NET Framework. Some class libraries, like the one containing the System namespace, are so common that they are added to your application implicitly. Additional libraries can be selected from this dialog. In the dialog, click the Browse tab, then locate and select the TimeLibrary.dll file (located in the bin\Release directory of the TimeLibrary project we created in Steps 14) as shown in Fig. 9.21. Click OK to add the reference to the project.
Figure 9.21. Adding a Reference. After adding the reference, you can use keyword Imports followed by the namespace name TimeLibrary (line 3) to inform the compiler that you are using classes from this namespace. Module TimeLibraryTest and class Time are in different namespaces, so the Imports statement at line 3 allows module TimeLibraryTest to use class Time.
The Imports statement at line 3 is not required if you refer to class Time with its fully qualified nameTimeLibrary.Timewhich includes the namespace name and the class name. For example, line 7 could be written as
Dim time As New TimeLibrary.Time() You can use this fully qualified name in your programs, or you can import the class and use its simple name (the unqualified class nameTime). If another namespace also contains a Time class, fully qualified class names can be used to distinguish between the two Time classes and prevent a name conflict (also called a name collision).
| |