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.
Listing 14.3 Code for the myComponent Class

'''' 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

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.
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.
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.
Figure 14.4. Modifying the AssemblyInfo attributes.

Change the following assembly attributes to the listed values:
AssemblyTitle
myComponent
AssemblyDescription
My first .NET component
AssemblyProduct
Made with Visual Studio .NET
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.
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.
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.
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.
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:
.NET component
COM component
Project
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.
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:
Drag a TextBox from the Toolbox to the form.
Drag another TextBox control from the Toolbox to the form.
Drag a CommandButton control from the Toolbox to the form, and set its Text property to DoMath and set its Name property to DoMath.
Drag another CommandButton control from the Toolbox to the form, and set its Text property to DoName and set its Name property to DoName.
Drag a DataGrid control from the Toolbox to the form.
Arrange the controls so that they look something like Figure 14.10.
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:
Imports Sams.Day14
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.
Listing 14.4 Code for the DoMath_Click Event

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

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.
Note
The input parameters and return values of a method are known as the method''''s signature.
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.
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.
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 Day 7, "Exceptions, Debugging, and Tracing" you learned that errors bubble up to the first method in the calling chain that has an error handler. If you''''re writing the components and consuming them in your own applications, you can implement error handling wherever you want because you''''re the only one using the component. If you plan to distribute the component for others to use, you can''''t assume that they''''ll implement error handling. That means you should handle errors in the component itself by using the Throw statement if an error occurs. The following snippet should refresh your memory regarding what you learned about handling errors on Day 7:
Try
Catch e as Exception
Throw e
Finally
By throwing the exception to the caller, you''''re passing the correct error information and you''''re making sure that your code isn''''t causing the system to crash.
Note
You write code to consume the rest of the methods and properties in your component in the exercises at the end of the day.
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.