This documentation is archived and is not being maintained.

Introduction to the Visual Studio 2005 Application Designer, Part 2

Visual Studio 2005
 

Tony Loton
LOTONtech Limited

February 2005

Summary: Get a practical introduction to Application Designer, moving from design to implementation of a service-oriented system. (17 printed pages)

Download the ApplicationDesignerExample.exe file.

Note   This is the same download that is available in Part 1 of this series. It's available here as well for your convenience.

Contents

Introduction
Designing a Service-Oriented Application
Introducing Other Application Types
Conclusion

Introduction

In Part 1 of this series, I introduced you to Application Designer, and showed you how to design a currency conversion service-oriented example using it.

In this article, I'll show you how to implement that distributed system using Visual Studio 2005 Team Architect, then wrap-up by discussing how some of the other application types—namely external Web services and external databases—can be incorporated into an overall design.

Designing a Service-Oriented Application

Having devised the overall application design, it is now possible to generate skeleton implementations of the applications that comprise the design. This is simply a matter of right-clicking any blank portion of the diagram and choosing Implement All Applications.

Before doing that, I made things more interesting by setting different implementation languages for the various applications. I clicked each application in turn, and using the Properties window I set the Language property as follows:

  • BureauDeChange to be implemented in Visual C#
  • CurrencyConverter to be implemented in Visual Basic
  • DollarExchangeApp to be implemented in Visual Basic
  • EuroExchangeApp to be implemented in Visual C#

Having made those changes, initiating the Implement All Applications feature launches the dialog box shown in Figure 1. It allows me to confirm that the implementation language (as above) and the application template (Empty Web Site in all cases) for each application is correct.

ms379583.introappdesigner2-fig01(en-US,VS.80).gif

Figure 1. Confirm Application Implementation dialog box

What You Get for Implemented Applications

For each of the implemented applications, a project is created within the solution. Not only is skeleton code created—as you would expect from UML code generation tools—but also all of the supporting files that are necessary for each application to run as a Web page or Web service. This is shown in Figure 2.

ms379583.introappdesigner2-fig02(en-US,VS.80).gif

Figure 2. Solution Explorer showing Implemented Applications

In Figure 2 I've highlighted the USDollarService.asmx file because I'm about to show you what happens when I right-click that file and choose View in Browser.

The browser launches using a URL that points directly to the Web service referred to by the .asmx file, initially displaying a list of all operations provided by that Web service as you can see in Figure 3.

ms379583.introappdesigner2-fig03(en-US,VS.80).gif

Figure 3. USDollarService Web service (all operations)

Note   The Web service itself has been started automatically in the Visual Web Developer Web Server as a result of implementing the application.

If you're familiar with Web services, this illustration will not surprise you, and you'll know that I could go on to test each of the operations by providing input to a HTML form and examining the Web response.

Testing the operations at this point is futile though, because they've not yet been fully implemented, and that's the main point I want to make here. Just because Visual Studio has generated skeleton classes for the Web services, and generated the supporting files required by IIS, and even started up those services, that doesn't mean that those services are doing anything useful. There's still a little coding work to do, but not much.

The same is true of the front-end Web applications, which I could launch by right-clicking on the .aspx files (DollarExchangeApp.aspx) and choosing View in Browser. The result—a blank page!

Looking back at Figure 2 you might also notice a file type that is not recognizably required by IIS. I'm talking about .sdm files, or System Definition Model (SDM) documents. SDM provides the basis for the underlying metamodel used by Distributed System Designers. These .sdm files, one per application, describe the characteristics of the applications in an XML format that may be processed by other tools; for example, when evaluating deployment using Deployment Designer. They appear after implementing applications defined on an application diagram, or after adding an externally implemented application definition, such as an external Web service, to the application diagram. In most circumstances you can safely ignore them. In fact, you are strongly advised never to edit these files directly.

Try It!

Assuming you've recreated my application design, or loaded it up from the ApplicationDesigner.ad file that I supplied, you can now have a go at implementing the applications. Set each application to be implemented using the relevant language, then right-click an empty portion of the diagram and choose Implement All Applications.

You might want to make a copy of the ApplicationDesign.ad file first, because once you've implemented the applications in this file, you can't use that diagram as the basis of an application design in another solution without re-implementing all the definitions.

Coding the Implementations

Although I have used Visual Studio to generate skeleton implementations for all of the applications, at this point those implementations will not do anything useful. However, much of the hard work has been done, so it won't take much additional code to make these applications work end-to-end, at least for demonstration purposes.

Let's take a look at each of the applications and go through the extra code that I added to each implementation to make it work.

BureauDeChange Implementation

If you look back a Figure 2, you'll see the file ExchangeRateService.asmx listed within the BureauDeChange application project. The content of that file, the entry point for the Web service, is as follows:

<%@ webservice class="BureauDeChange.ExchangeRateService" language="c#" 
codebehind="~/Application_Code/ExchangeRateService.cs" %>

From that information I can determine the code-behind file that implements the service, and navigate to it in Solution Explorer, or simply right-click the .asmx file and choose View Code from the Context menu.

The following listing shows the skeleton code that has been generated by Visual Studio as a starting point for the service implementation. Notice that the comments I entered as part of the Summary information in Part 1 of this series have been included.

namespace BureauDeChange
{
  [System.Web.Services.WebServiceBinding(Name = "ExchangeRateService")]
  public class ExchangeRateService : System.Web.Services.WebService
  {
    /// <summary>
    /// This operation provides the market conversion rate between fromCurrency and toCurrency.
    /// </summary>
    /// <param name="fromCurrency">A currency code such as "USD" or "EUR".</param>
    /// <param name="toCurrency">A currency code such as "USD" or "EUR".</param>
    [System.Web.Services.WebMethod(), 
System.Web.Services.Protocols.SoapDocumentMethod(Binding = "ExchangeRateService")]
    public double getExchangeRate(string fromCurrency, string toCurrency)
    {
      throw new System.NotImplementedException();
    }
  }
}

It's within the method body of getExchangeRate that the action should happen, so I modify that to include the following lines of code immediately before the throw statement.

if (fromCurrency.Equals("USD") && toCurrency.Equals("EUR"))
  return 0.78;

if (fromCurrency.Equals("EUR") && toCurrency.Equals("USD"))
  return 1.28;

For convenience, I've chosen to retain the throw statement as the last line of the method so that a NotImplementedException will be thrown for any currency conversion that is not yet implemented. As it stands, that means conversions to and from pounds sterling, which you could add if you like when you try this out.

Having added just those lines of code, and saving the changes, I can test out the Web service. So, I right-click the file ExchangeRateService.asmx and choose View in Browser to see a page similar to that given in Figure 3, only this time listing the getExchangeRate operation of the ExchangeRateService.

Selecting that operation takes me to the form shown in Figure 4, which allows me to enter arguments for the fromCurrency and toCurrency parameters prior to invoking the Web service.

ms379583.introappdesigner2-fig04(en-US,VS.80).gif

Figure 4. getExchangeRate Web service operation

That's one of the things I really like about Web services—the fact that you can test them using an automatically generated HTML form without having to implement a real client first.

The result of that Web operation invocation is given in Figure 5. A quick look back at the code confirms that the result, 0.78, is exactly what I expected. And I could retest the service with "EUR" as the argument for the fromCurrency parameter and "USD" as the argument for the toCurrency parameter to yield the result 1.28.

ms379583.introappdesigner2-fig05(en-US,VS.80).gif

Figure 5. getExchangeRateService results

There's nothing to stop you coding up this implementation and testing it by following my steps given above. But I'll invite you to formally try it out at the end of this section, once I've run through all of the implementations.

CurrencyConverter Implementation

The CurrencyConverter application provides two Web services. I'll show you how I completed the implementation of the USDollarService and leave it to you to figure out how to implement the complementary EuroService. As you'll see, it's not rocket science.

First, I right-click the USDollarService.asmx file and choose View Code. The skeleton code that was generated by Visual Studio looks like this:

Imports System.Web
Imports System.Web.Services
Imports System.Web.Services.Protocols

Namespace CurrencyConverter

  <System.Web.Services.WebServiceBinding(Name:="USDollarService")> _
  Public Class USDollarService
    Inherits System.Web.Services.WebService

    '''
    <System.Web.Services.WebMethod()> _
<System.Web.Services.Protocols.SoapDocumentMethod(Binding:="USDollarService")> _
    Public Function fromEuros(ByVal amount As Double) As Double

    End Function

    '''
    <System.Web.Services.WebMethod()> _
<System.Web.Services.Protocols.SoapDocumentMethod(Binding:="USDollarService")> _
    Public Function fromPoundsSterling(ByVal amount As Double) As Double

    End Function
  End Class

End Namespace

To complete the implementations of the Web services, I enter a few lines of code into the bodies of the Web methods. In the case of the fromEuros method, the required code is:

Dim rate As Double
Dim exchangeService As New CurrencyConverter.WebServiceProxies.ExchangeRateService
rate = exchangeService.getExchangeRate("EUR", "USD")
Return amount * rate

What that code does is to set up a proxy to the ExchangeRateService provided by the BureauDeChange application, invoke the getExchangeRate operation of that service, and then return the amount in dollars as the amount supplied (in Euros) multiplied by the exchange rate.

Note   A proxy is a local object that you can invoke as though it is the remote Web service itself, though actually it isn't. Internally the proxy formulates an appropriate SOAP request and unpacks the response without you ever having to be aware of how that works. In effect, the proxy notionally fills out the form in Figure 4 and captures the response shown in Figure 5.

Once that code has been entered and saved, I am able to test the implementation of the fromEuros operation provided by the USDollarService of the CurrencyConverter application in exactly the same way that I previously tested the getExchangeRate operation provided by the ExchangeRateService of BureauDeChange application. Simply by viewing file USDollarService.asmx in the browser, choosing the fromEuros operation, and filling out the HTML form that will be similar to that shown in Figure 4, though this time asking for an amount (in Euros) as input.

When I enter the amount 100 in Euros, the response in Dollars is as follows:

  <?xml version="1.0" encoding="utf-8" ?> 
  <double xmlns="http://tempuri.org/">128</double>

DollarExchangeApp Implementation

The implementation of the DollarExchangeApp, which I'll now describe, also serves to demonstrate the implementation of the EuroExchangeApp, which is almost identical. As a starting point, Visual Studio will have generated a default Web page—Default.aspx—with the following content.

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="Default.aspx.vb" Inherits="Default_aspx" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
    
    </div>
    </form>
</body>
</html>

I used the Web Forms Designer to construct a UI for the application, which you can get a feel for by looking ahead to Figure 6 below. As a consequence of designing the form, the following HTML code appears within the <div> and </div> tags in the above listing:

<asp:Label ID="Label1" Runat="server" Text="Enter amount in Euros" 
Width="142px" Height="19px"></asp:Label>
<asp:TextBox ID="euroAmount" Runat="server"></asp:TextBox>
<asp:Button ID="convertButton" Runat="server" Text="Convert to US Dollars" 
OnClick="convertButton_Click" /> &nbsp;<br />
<asp:Label ID="Label2" Runat="server" Text="Amount in US Dollars is" 
Width="158px" Height="19px"></asp:Label>
<asp:TextBox ID="dollarAmount" Runat="server"></asp:TextBox>

When you come to implement this application yourself, you can simply paste that code into the Default.aspx file rather than re-designing the form yourself.

Besides the UI code, I needed an event handler for the button, so in the form design view I double-clicked the button and entered the following code.

Protected Sub convertButton_Click(ByVal sender As Object, ByVal e As System.EventArgs)
  Dim dollarService As New DollarExchangeApp.WebServiceProxies.USDollarService
  dollarAmount.Text = dollarService.fromEuros(Double.Parse(euroAmount.Text))
End Sub

This code creates a proxy to the USDollarService, and invokes it, in the same way that the USDollarService invoked the ExchangeRateService previously.

The amount to be converted from Euros to US Dollars is taken from the text box named euroAmount and the resulting amount in dollars is displayed in the text box labeled dollarAmount. Figure 6 shows what happened when I tested this application.

ms379583.introappdesigner2-fig06(en-US,VS.80).gif

Figure 6. DollarExchangeApp

Try It!

You can now have a go at completing the implementation of the DollarExchangeApp and the complementary EuroExchangeApp as described above. If you haven't already done so, you'll first need to complete the implementations of the other Web service applications.

Introducing Other Application Types

So far in this article series, I have demonstrated the use of Application Designer in the context of a distributed system comprising interconnected Web applications and Web services. This is because the Application Designer strongly supports Web services design, and there is little additional work that needs to be done in order to design Web applications.

Of course, Application Designer can be used to design quite a few other application types—database applications, BizTalk service applications, Windows and Office applications, and so on. So no coverage of Application Designer would be complete without at least mentioning some of the other application prototypes that may be used to design a distributed system. I'll now take two of the other applications types—an external Web service and an external database—and for each one I'll show how it may be incorporated into my design.

ExternalWebService

When I first introduced the overall design of my distributed system, I hinted that in reality the BureauDeChange application might be provided by a third party. In fact, as long as they all agreed on the definition of the ExchangeRateService, there could be several third-party organizations providing the same service, and I could connect up to the one that offers the best rates of exchange.

Suppose there is a least one third-party supplier. To connect to its service, I simply have to drag an ExternalWebService prototype from the Toolbox and enter the URL of the Web service into the dialog box as shown in Figure 7.

ms379583.introappdesigner2-fig07(en-US,VS.80).gif

Figure 7. Add Web Reference

In this example, I have taken advantage of the fact that I already had an ExchangeRateService Web service running from my earlier implementation examples, so I've used the URL for that as though it was a URL provided by a third-party supplier. Upon clicking the Add Reference button, a new Web service provider endpoint named ExchangeRateService is added to my diagram, attached to a new application of the same name, as shown in Figure 8.

ms379583.introappdesigner2-fig08(en-US,VS.80).gif

Figure 8. Application Design with an External Web Service

Apart from the difference in the name of the application, the ExchangeRateService of this external Web service is, from client's perspective, equivalent to the ExchangeRateService of the BureauDeChange application that I implemented myself. As a result, I've connected it up to the CurrencyConverter in the same way.

ExternalDatabase

Regardless of whether I implement the ExchangeRateService myself, or rely on a third-party supplier, the chances are that the service will source its exchange rate information ultimately from a database.

Using my own implementation, I can show this on an application diagram by dragging an ExternalDatabase prototype from the Toolbox. In Figure 9, I've done just that, and renamed the database to ExchangeRates before connecting it up to the BureauDeChange application.

ms379583.introappdesigner2-fig09(en-US,VS.80).gif

Figure 9. Application Design with ExternalDatabase

When connecting the database to a client application, Visual Studio prompts for a data source. You have the option of simply canceling out at this point, thereby deferring the definition of the data source, or connecting at a later time. I was expecting that dialog, of course, so in anticipation I had already created a SQL Server database to serve as that data source. This is done by right-clicking the Data Connections entry in the Server Explorer and choosing Create New SQL Server database.

Figure 10 and Figure 11 show the details that I entered in order to complete the connection to my sample database.

ms379583.introappdesigner2-fig10(en-US,VS.80).gif

Figure 10. Choose Data Source

ms379583.introappdesigner2-fig11(en-US,VS.80).gif

Figure 11. Connection Properties

Conclusion

Application Designer represents one piece of the Team Architect jigsaw puzzle. In its own right, it is very useful as a means of designing applications and then implementing them with minimal effort. But to get maximum value out of this visual designer, it is important to take it in the context of the other designers. My follow-up article will demonstrate the next logical step of using System Designer to design deployable systems that are composed from applications.

Tony Loton is an MCP who wears various hats as Principal Consultant/Director of LOTONtech Limited, as Principal Consultant/Head of Microsoft Practice at Cogenture, and as Associate Lecturer with the UK's Open University. He is currently co-authoring the book Professional Visual Studio 2005 Team System (ISBN 0764584367) to be published by Wiley/Wrox in summer 2005.

Show: