Sams Teach Yourself Visual Studio .NET 2003 in 21 Days

Sams Teach Yourself .Net in 21 Days

By Jason Beres

Creating a Class Library Application

To create your new component, start Visual Studio .NET and create a new Class Library application called myComponent_vb or myComponent_cs, depending on what language you're writing in.

In the myComponent application, you're going to write simple methods and properties that are exposed to consumers of the component. You are also going to create a namespace for your component. By default, the namespace name is normally the name of the application. You're going to change this to implement your own namespace.

To implement the functionality of your component, type the code in Listing 14.3 in the default Class1 class that's added to the Class Library application.

As you're entering the code, read the comments for each item to understand how it's being used. You're going to add methods that return a dataset; two methods that have the same name, but have different in and out parameters, and you're going to implement read/write and read-only properties. The functionality you implement here is common to what you would need to do in real-world scenarios.

Example 14.3. Code for the myComponent Class

vbnet_icon.gif
' You are using SQL Server, so you must import the
' SqlClient namespace
Imports System.Data.SqlClient

' This is your top-level namespace
Namespace Sams

    ' This is the child namespace for the Sams namespace
    Namespace Day14

        ' The name of the class, NewClass
        Public Class NewClass

            ' These are private variables to be used when
            ' setting and retrieving the Properties
            Private m_Fname As String
            Private m_LName As String

            ' A function that returns a DataSet to the caller
            Function GetAuthors(ByVal ConnectionString As String) _
                    As DataSet
                Dim cn As SqlConnection =
                    New SqlConnection(ConnectionString)
                Dim cmd As New SqlCommand("Select * from Authors", cn)
                Dim adp As New SqlDataAdapter()
                adp.SelectCommand = cmd
                Dim ds As DataSet
                adp.Fill(ds, "Authors")
                Return ds
            End Function

            ' Generic Math Function with Integer as return value
            Function DoMath(ByVal num1 As Integer, _
                ByVal num2 As Integer) As Integer

                Return num1 * num2

            End Function

            ' Generic Math Function with Integer as return value
            Function DoMath(ByVal num1 As Integer, _
                 ByVal num2 As Integer, ByVal num3 as Integer) As Integer

                Return num1 * num2

            End Function

            ' Read/Write property for FirstName
            Property FirstName()
                Get
                    Return m_Fname
                End Get

                Set(ByVal Value)
                    m_LName = Value
                End Set
            End Property

            'Read/Write property for LastName
            Property LastName()
                Get
                    Return m_Fname
                End Get

                Set(ByVal Value)
                    m_Fname = Value
                End Set
            End Property

            ' Read-only property to return the full name
            ReadOnly Property FullName()
                Get
                    Return m_Fname & " " & m_LName
                End Get
            End Property

        End Class

    End Namespace

End Namespace

c_icon.gif
using System;
using System.Data;
using System.Data.SqlClient;

namespace Sams
{
   namespace Day14
   {
      public class NewClass
      {
         public NewClass()
         {
         }
         // These are private variables to be used when
         // setting and retrieving the Properties
         string m_Fname;
         string m_Lname;

         // A function that returns a DataSet to the caller
         public System.Data.DataSet getCustomers(string ConnectionString)
         {
            SqlConnection cn = new SqlConnection
               (ConnectionString);
            SqlDataAdapter da  = new SqlDataAdapter
                ("SELECT * from Authors", cn);
            DataSet ds = new DataSet();
            da.Fill(ds, "Authors");
            return ds;
         }

         // Generic Math Function with Integer as return value
         public int doMath(int num1, int num2)
         {
            return num1 * num2;
         }

         // Generic Math Function with Decimal as return value
         public int doMath(int num1, int num2, int num3)
         {
            return num1 * num2 * num3;
         }

         // Read/Write property for FirstName
         public string firstName
         {
            get
            {
               return m_Fname;
            }
            set
            {
               m_Fname =value;
            }
         }

         // Read/Write property for LastName
         public string lastName
         {
            get
            {
               return m_Lname;
            }
            set
            {
               m_Lname = value;
            }
         }

         // Return the Fullname value
         public string FullName
         {
            get
            {
               return m_Fname + " " + m_Lname;
            }
         }
      }
   }
}

As you're writing components, remember that the Class view gives you a bird's-eye view of what your classes contain. If you're coding in C#, you can use the Class view to add types to your class very easily. Figure 14.2 shows the right-click power of the Class view to add a new property to a C# class file.

14fig02.jpg

Figure 14.2 Using the Class view to add types to your class file.

After you select New Property from the contextual menu, the Add Property Wizard screen enables you to easily add a type name, data type, return value, and any comments that you would like to with the type, as Figure 14.3 demonstrates. Using the Class view in C# to add types to your classes makes doing so fast and simple.

14fig03.jpg

Figure 14.3 The C# Add Property Wizard.

Now that you've written the code for the class, you need to compile the application into an assembly. But before you do that, you might want to update the AssemblyInfo file in your solution. The AssemblyInfo file contains attributes that describe your component. By specifying the correct data in the attribute, those properties are compiled into the assembly, and they can be viewed by consumers of the assembly.

If you double-click the AssemblyInfo.vb or AssemblyInfo.cs file in your solution, you should see something like Figure 14.4. Figure 14.4 is the AssemblyInfo.vb for a Visual Basic .NET project.

14fig04.jpg

Figure 14.4 Modifying the AssemblyInfo attributes.

Change the following assembly attributes to the listed values:

Next, you need to modify the root namespace of the component. If you're coding in C#, you don't have to worry about it: C# takes the namespace information from the class file itself. In Visual Basic .NET, you must right-click on the project name in the Solution Explorer, and select Properties from the contextual menu to get to the Project Properties dialog.

In the myComponent_vb Property Pages dialog, the root namespace is set to myComponent. Delete this value and leave the Root namespace box blank, as demonstrated in Figure 14.5.

14fig05.jpg

Figure 14.5 Removing the root namespace in the Property Pages dialog.

By removing the root namespace property from the project, the namespace defined in your class file can be used by other applications. This makes it easy to create namespaces that span multiple projects.

Because C# takes the namespace name from the class file itself, there's still a useful property you can change in the properties for the project. If you're coding in C#, right-click the project name in the Solution Explorer and select Properties from the contextual menu. When the MyComponent_cs Property Pages dialog pops up, change the default namespace to Sams (see Figure 14.6). Now, each class file added to your application has the default namespace of Sams.

14fig06.jpg

Figure 14.6 Setting the default namespace in a C# project.

Now you're ready to build the component. If you right-click the project name in the Solution Explorer and select Build from the contextual menu, your component will be compiled into a managed DLL.

The next step is to consume the DLL from a client application.

Consuming the Class Library Application

To consume the DLL you just created from another application, you can simply add another project to your solution. Adding multiple projects to a single solution makes it very easy to debug. You can set breakpoints in any of the projects, and as they're hit, the code execution stops. This even works if the components are written in a different language from the consumer of the component.

To test this, right-click the myComponent solution in the Solution Explorer, and select Add, New Project from the contextual menu. When the Add New Project dialog pops up, select a new Windows Forms application, and name it TestConsumer_vb or TestConsumer_cs, depending on the language you're writing in. Figure 14.7 demonstrates this. You now have two projects in your solution.

14fig07.jpg

Figure 14.7 Adding a new project to the myComponent solution.

Next, you need to tell the solution that the TestConsumer project is the startup project. That means when you press the F5 key to run the application, the Windows Forms application starts, not the Class Library application.

To do this, you can right-click the TestConsumer project name in either the Solution Explorer or the Class view, and select Set As StartUp Project from the contextual menu, as Figure 14.8 shows.

14fig08.jpg

Figure 14.8 Setting a startup project.

After you set the startup project, it appears in bold in the Solution Explorer.

To consume the component, you must add a reference to it in the TestConsumer project. To do so, right-click the References node in the Solution Explorer and select Add Reference from the contextual menu. As you learned a few days ago when we discussed namespaces, you can add three types of references to an application:

Because you have a component in your solution, you can click the Projects tab, and you'll see the myComponent project in the list. Select the myComponent project, click the Select button, and click the OK button, as Figure 14.9 demonstrates.

14fig09.jpg

Figure 14.9 Adding your component to the TestConsumer application.

Now you can reference the component in the Windows Forms application as you would any other assembly.

To set up your form, do the following:

  1. Drag a TextBox from the Toolbox to the form.

  2. Drag another TextBox control from the Toolbox to the form.

  3. Drag a CommandButton control from the Toolbox to the form, and set its Text property to DoMath and set its Name property to DoMath.

  4. Drag another CommandButton control from the Toolbox to the form, and set its Text property to DoName and set its Name property to DoName.

  5. Drag a DataGrid control from the Toolbox to the form.

Arrange the controls so that they look something like Figure 14.10.

14fig10.jpg

Figure 14.10 Form1 of the TestConsumer application after adding controls.

Next, double-click the form to get to the code-behind for Form1.

At the top of the class file, alias your component with the Imports statement in Visual Basic .NET or the using statement in C#. Your code should look like the following:

vbnet_icon.gif
Imports Sams.Day14

c_icon.gif
using Sams.Day14;

By adding the component as a reference, it's available to your application. And by correctly setting up the namespace, you avoid using the name of the physical file as you did in Visual Basic 6, and can use the metadata from the assembly to determine the correct namespace.

Now, you need to add code to the DoMath and DoName click events.

If you double-click on the DoMath button, add the code in Listing 14.4.

Example 14.4. Code for the DoMath_Click Event

vbnet_icon.gif
Private Sub DoMath_Click(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles DoMath.Click

    Dim x As New NewClass()

    MessageBox.Show(x.DoMath(TextBox1.Text, TextBox2.Text))

End Sub

c_icon.gif
private void DoMath_Click(object sender, System.EventArgs e)
{
   NewClass x = new NewClass();
   int retVal;
   retVal = (x.doMath(Convert.ToInt32(textBox1.Text),
               Convert.ToInt32(textBox2.Text)));
   MessageBox.Show(retVal.ToString());
}

When you were typing along, you probably noticed the auto-list members and autocomplete available to you. After you create a new instance of the component class, all the properties, methods, and events are available to the application consuming the component.

You were also introduced to a very cool object-oriented feature in .NET called overloading. When a method is overloaded, it means there are multiple methods with the same name, but they have different data types for the input parameters or return values. They also can have a different number of input parameters. In the DoMath method you created in your component, there were two DoMath methods: one had two input parameters and the other had three. Depending on the data you pass to the method, .NET correctly figures out the correct method to use with the least amount of overhead.

Figure 14.11 shows the power of the Visual Studio .NET integrated development environment (IDE) when using components. Notice that the methods and properties for your component are listed, as well as a tooltip indicating that the method is overloaded and how many overloaded methods it has.

14fig11.jpg

Figure 14.11 Using auto-complete with your component in .NET.

Now if you press F5 to run your application and click the DoMath button, you get a MessageBox back with the value.

Another extremely powerful tool is the Project Build Order property. Let's say that you have more than one component, and certain components depend on other components being successfully built before they can be built. If you have a bunch of projects in your Solution Explorer, you can set the order in which they're built by right-clicking on the solution name and selecting Project Build Order from the contextual menu. You get a dialog like the one in Figure 14.12 that enables you to specify the order in which the components should be built.

14fig12.jpg

Figure 14.12 Specifying the build order for a solution.

If you have multiple projects in a solution and a component in one of the projects is giving you problems, and nothing else is dependent on it, you can right-click on the project name of the component and select Remove from the contextual menu. Doing so removes the project form the solution. You can always add the project back by right-clicking the solution and selecting Add, Add Exiting Project.

Now you know how to create a component in .NET using the Class Library template and consume that component from a client application. You can see that creating and debugging components in the .NET IDE is very simple by adding another project to your solution. The Class Library template makes up most of the component development that you'll do. Creating components using the design surfaces is a great Visual Studio .NET feature, but you're normally encapsulating specific application functionality into separate pieces, so you don't necessarily need a designer to do that.

In the future of the mobile world, you might implement most of your components as Web services, so the functionality can be exposed outside of your organization.

Share ThisShare This

Informit Network