Adding Classes to an XML Web Service
Once you have created your project template, Visual Studio .NET adds two classes to your project. These are the Global Class, which we will look at extensively in later hours, and the Service1 class, which we will focus on in this hour.
Service1, as the name implies, is a service. If you think of an XML Web service as a COM DLL, then a service is simply an object that is exposed by that DLL. An XML Web service project can contain many services, and we will see examples of that in Hour 23. The Global Class is a class that handles events throughout an XML Web service application, regardless of the number of services that we add to it. You will learn to use the global file in Hour 17.
When you examine a new service, you will notice that the template includes a few methods and some commented example code. The commented example code, seen in Listing 7.1 for Visual Basic and in Listing 7.2 for C#, will act as a model for every other method that you add to an XML Web service. Notice the addition of the <WebMethod> tag to the standard function declaration. This tag instructs .NET to expose this function to XML Web service consumers.
Listing 7.1 HelloWorld Method in Visual Basic
1: <WebMethod> Public Function HelloWorld() as String 2: HelloWorld = "Hello World" 3: End Function
Listing 7.2 HelloWorld Method in C#
1: [WebMethod] 2: Public String HelloWorld() 3: { 4: Return "Hello World" 5: }
Obviously, your calculator doesn't use the Hello World function, so you will leave the example code commented out, but it nicely reminds you what our calls should look like.
NOTE
If you create an XML Web service and find that some of your methods cannot be called from your client application, go back and check that you have included the <WebMethod> tag in your calls. Failure to include this tag will create methods that are exposed only to code within your XML Web service project.
Inheriting the WebService Class
When you create an XML Web service, what you are really doing is inheriting the WebService class and altering some of its methods. Two important things in your XML Web service code make this happen. The first is the inclusion of the System.Web.Services namespace, which occurs in the general declarations section of your code as follows:
Imports System.Web.Services
The second is the declaration of your service class, which has the following form:
Public Class ServiceName Inherits System.Web.Services.WebService
These two lines of code will exist in every XML Web service that you create, and they give you access to the framework of the XML Web services architecture. By building your class upon the WebService class, you can override the WebService constructors and destructors as well as add new methods.
NOTE
The Web Service Template Project in Visual Studio .NET will include WebService namespace and class declarations for you. Removing or altering these lines is a surefire way to ensure that your service doesn't function.
Calling the Constructor
By now, you have probably noticed a line in the pregenerated code that reads, "Web Services Designer Generated Code." Click on the plus sign next to that text to view the constructor function, New(). If you are in C#, you will not find the New() method but will instead find a public method with same name as your service. This method is known as the constructor in the traditional object-oriented programming model and is called whenever an object is created from your class.
This method is where you will add any initialization code that your object needs, such as setting the values of variables, connecting to a database, and so on. If you need initialization code to instantiate a custom object, place it here, after the InitializeComponent() call that .NET added for you. Listing 7.3 shows an example of initializing a custom object.
Listing 7.3 Using the New() Method to Initialize Objects
1: Public Sub New() 2: MyBase.New() 3: 4: 'CODEGEN: This procedure is required by the Web Services Designer 5: 'Do not modify it using the code editor. 6: InitializeComponent() 7: 8: Dim objConn as ADODB.Connection 9: Set objConn = New Connection 10: End Sub
Our four-function calculator doesn't require any initialization code, so we will leave the constructor as it is at this point. In Hours 11 and 17, we will see several examples of using the New() method in XML Web services.
NOTE
Do not add code to the New() method before the InitializeComponent() call. Code written before this line may cause serious errors at runtime.
The Dispose and Finalize Methods
Notice in our service that .NET has created a Dispose method for both Visual Basic and C# classes. This method is called when the service goes out of scope or is explicitly destroyed. This is the place in your service where you would perform garbage-collection activities, such as releasing database connections and destroying object references. This method is made public so that client code can call it before setting its reference equal to nothing.
ServiceName.Dispose()
NOTE
For those of you who haven't done much object-oriented programming, garbage collection is the term commonly used to refer to the act of reclaiming memory used by objects created in your code. It is important to destroy these objects when they are no longer needed in order to keep them from taking up valuable space in memory and causing your program to perform poorly.
.NET also allows you to add a method called Finalize. Finalize is the actual destructor of the service. In traditional object-oriented programming, this is where you would do your cleanup. Under the .NET model, however, both Dispose and Finalize can be called by the garbage collector. This is done with no guarantee as to the order in which those calls will be made or even as to when they will occur during execution. In fact, Microsoft goes so far as to caution that you cannot guarantee that the Finalize method will ever get called. Indeed, if you create a service and test for this method, you will see it occur infrequently.
Because of this, I recommend using Dispose for all your cleanup code and explicitly calling it in all your client applications. Finalize should then be used as a backup to ensure that references are dropped in the event that Dispose is not called explicitly by client code.
You will use the Dispose and Finalize methods heavily in Hours 14 and 17. Until then, just know that these methods are how you can exit your service gracefully.