In this section, we first provide an overview of the StockBroker distributed application design, so that you know what the system is meant to do. We then show you how to draw the diagram representing the design by dragging application prototypes and endpoints onto the diagram. In doing that, we show off as many of the Application Designer features as possible via the running example.
Figure 2-2 provides a pictorial representation of the distributed service-oriented system we'll be designing (the StockBroker system) in the format we'll be using to design it (as an application diagram), and drawn using Application Designer.
Our key application will be the StockBroker application, which exposes two ASP .NET Web services: the StockQuoteService (to report latest stock prices) and the DealingService (to enable stocks to be bought and sold).
Two end-user applications will be provided: a StockQuoteApp ASP .NETWebApplication that may be used for free over the Internet, and a more functional DealingApp WindowsApplication that may be downloaded by paid, registered users. StockQuoteApp will make use of the StockQuoteService, and DealingApp will make use of both the StockQuoteService and the DealingService.
The StockBroker application will take in latest stock prices via a direct feed from the stock market, using non-Microsoft technologies that we model as a GenericApplication. The StockBroker application will also make use of a third-party ASP .NET Web service provided by a MarketMaker, so as to place "buy" and "sell" deals.
Market Maker is a stock-broking term for a firm that stands ready to buy or sell a particular stock at a publicly quoted price, thereby creating a ready market in which buyers and sellers need not be matched on every deal.
To complete our design from a full solution perspective, we're showing that the MarketMaker places deals into a StockDatabase.
This design exhibits some interesting characteristics. First, it shows a layered service-oriented architecture whereby the services provided by the application-specific StockBroker application are supported by more generic business services provided by the MarketMaker application.
Second, while you could add some application-specific behavior into the StockBroker Dealing Service, you will certainly have noticed that it has the same name as a service provided by the MarketMaker. Though the internal implementations will be different, we intend the interfaces (i.e., the list of supported operations) to be the same, which effectively makes the MarketMaker version of the DealingService definition an ideal prototype for the definition of the same service on the StockBroker.
Finally, this design combines several services into a single application, so you have a single StockBroker application exposing StockQuote and Dealing services, rather than separate StockQuote and Dealing applications. This is reminiscent of UML component modeling, which enables you to define a system in terms of components that expose multiple interfaces. This is shown in Figure 2-3, which is an equivalent UML component diagram (drawn using Visio) for the design shown in Figure 2-2.
If you have a UML background, you will now see how key concepts translate between the two notations. An application in Application Designer is analogous to a component in UML, and an endpoint is equivalent to a UML interface.
You might also have noticed that in the UML representation, we have distinguished between the types of components using stereotypes such as <<ASP .NET Web service>> and <<ASP .NET Web Application>>. This is necessary because UML component notation is not a domain-specific language, whereas Application Designer notation is specific to the .NET Framework.
In Chapter 1 we indicated that a DSL for Web service design and assembly should contain concepts such as Web services, web methods, and protocols. Application Designer does this through the mechanism of prototypes, which is much more powerful than the UML stereotype mechanism.
In this section, you'll see how you can set about drawing the diagram shown in Figure 2-2 yourself. As a starting point, you'll need a Distributed System Solution containing an application diagram. Choose File StockBrokerApplicationDesign."
The new solution will include a file with the extension .ad to designate it as an application diagram—in this case, named StockBrokerApplicationDesign.ad. Remember that you are allowed only one such diagram in your solution.
The other way to begin using Application Designer is to add an application diagram to an existing solution. This will reverse engineer all application types supported by the Application Designer.
The diagram is constructed by dragging application prototypes from the toolbox that was shown in Figure 2-1. You'll need to drag five application prototypes from the toolbox onto the design surface:
A GenericApplication prototype, to be named StockMarket
An ASP .NETWebService prototype, to be named MarketMaker
An ASP .NETWebService prototype, to be named StockBroker
An ASP .NETWebApplication prototype, to be named StockQuoteApp
A WindowsApplication prototype, to be named DealingApp
You can name each one by simply clicking its name label on the diagram, or by revealing its properties.
You should connect the applications together via their endpoints positioned around the edges of the application shapes. As you place each application onto the diagram, it will have one or more provider endpoints attached by default, and you can drag additional endpoints from the toolbox onto your applications as needed.
You need a total of four provider endpoints:
A GenericEndpoint on the StockMarket application, named StockPriceFeed
A WebServiceEndpoint on the MarketMaker application, named DealingService
A WebServiceEndpoint on the StockBroker application, named StockQuoteService
A WebServiceEndpoint on the StockBroker application, named DealingService
You can right-click any endpoint and choose Show Label from the context menu to reveal its name; then change the name by clicking the label or via its properties. You will notice the endpoints rendered as different icons according to their types; and as you complete the picture, you will see that provider endpoints are shown filled, whereas consumer (client) endpoints are shown hollow.
Now you need to connect these provider endpoints to their client applications in the configuration shown in Figure 2-2:
Connect the StockPriceFeed endpoint provided by the StockMarket application to the StockBroker application.
Connect the DealingService provided by the MarketMaker application to the StockBroker application. Rename the resulting consumer endpoint to DealingServiceMM.
Connect the StockQuoteService endpoint provided by the StockBroker application to the StockQuoteApp.
Connect the StockQuotesService endpoint and the DealingService endpoint, both provided by the StockBroker application, to the DealingApp. Rename the consumer end of the DealingService to DealingServiceSB.
In all cases, you can form a connection by moving the mouse over a provider endpoint, pressing the Alt key to see the mouse cursor change, and then moving the mouse cursor to an appropriate consumer endpoint or client application itself. Alternatively, you can use the Connection tool provided in the toolbox.
Note that these instructions encouraged you to name all of the provider endpoints first, and then connect them up to their client applications to create corresponding consumer endpoints. If you had connected the MarketMaker DealingService endpoint to the StockBroker application immediately after adding that provider endpoint, you would have created a consumer endpoint on the StockBroker with a default name of DealingService, which would prevent you from subsequently adding a DealingService provider endpoint to the StockBroker. Another way around that problem is to rename the StockBroker DealingService consumer endpoint to DealingServiceMM as soon as you place it—as we have in Figure 2-2.
Your final result should match ours from Figure 2-2 except that at this point your diagram will not show the StockDatabase. That's because placing an ExternalDatabase on the diagram requires some additional effort beyond simply dragging the appropriate prototype from the toolbox, as we'll now describe.
We've included an ExternalDatabase in our design for illustration, but to keep it simple for you and to stick to the main focus of this chapter—which is not database modeling—we won't be taking it any further into implementation, so you can regard that as optional.
However, on the assumption that curiosity is bound to get the better of you, we should at least tell you what will happen if you drag an ExternalDatabase prototype onto the diagram and try to connect to it.
You can drag an ExternalDatabase prototype onto the diagram and rename it StockDatabase to match ours. You will see that the default provider endpoint for the database will also rename automatically to StockDatabase.
So far so good, until you attempt to connect the provider endpoint to the MarketMaker client application, which will require you to configure a connection.
A Connection Properties dialog box will appear, as shown in Figure 2-4. From here you must select a data provider (such as SQL Server or ODBC) and a set of connection properties (as shown).
Here's a tip: If you've installed Visual Studio 2005 with the SQL Server 2005 Express Edition, you can create an empty database to use in this dialog by right-clicking Data Connections and choosing Create New SQL Server Database. In the dialog that appears, enter YourComputerName\SQLEXPRESS as the server name and StockDatabase as the database name. Once the database has been created, you can use the same server name and database name in this dialog.
Though the figure shows connection properties for a SQL Server database, your connection properties may well be for an Access, Oracle, or any other database depending on your provider selection.
In fact, this Connection Properties dialog is the same one that appears if you connect to a database from Server Explorer. In many cases, application prototypes you use are effectively pictorial routes into the existing Visual Studio wizards and features, and the same is true of ASP .NET websites and Web services.
The connection to the database will appear on the diagram after you confirm your settings. However, if you really don't want to configure your database connection at this point, you can simply cancel the Connection Properties dialog.
Keep in mind that this necessary restriction on not being able to visualize certain connections on the diagram until you have configured them also applies to external Web services (described later) and BizTalk services.
Application definitions do not contain hard-coded connection information, making it possible to specify the database connection during deployment.
By clicking one of the WebServiceEndpoints on the diagram, you can gain access to the Web service Details window, which is where you define the operations provided by the Web service. Figure 2-5 gives an indication of what you might see when you click the DealingService provider endpoint.
Of course, it won't look exactly like that for you because you've not yet added the operations. Do that now by clicking the <add operation> and <add parameter> indicators as appropriate, making sure that the result matches Figure 2-5. Everything you enter here will find its way into the implementation code, which in Visual C# will ultimately include the following method declarations:
public int buyStock(string stockSymbol, int numberOfShares) public int sellStock(string stockSymbol, int numberOfShares)
The endpoint details for the MarketMaker DealingService should be made identical but don't rush in and do that just yet. For now, just add an operation to the StockQuoteService endpoint to match this Visual Basic signature:
Public Function getQuote(ByVal stockSymbol As System.String) As System.Double
We've shown the method signatures here in two different languages for good reason. The DealingService methods will be implemented in Visual C#, and the StockQuoteService methods will be implemented in Visual Basic. The operation and parameter types shown in the Web service Details window will reflect the implementation language, which by default will be Visual Basic for each application. You can enter Web service details using Visual Basic types at this stage yet still change the implementation language later to Visual C#.
Our design allows for the two applications, Stockbroker and MarketMaker, to expose the same service—that is, the same service interface with different underlying implementations. As you've just entered the endpoint details for the DealingService endpoint located on the StockBroker application, it seems a shame to do all that work again for the benefit of the MarketMaker application, doesn't it?
Fortunately, you don't have to do all that work again because you can use the endpoint from one application as a prototype for an identical endpoint on another application. Right-click the DealingService endpoint and select Add to Toolbox from the context menu to launch the Add to Toolbox dialog box shown in Figure 2-6.
You can also copy and paste the application or copy the endpoint from one application to another. You don't need to create a toolbox entry to do this.
Upon completing that dialog box, you will be prompted to save the prototype into a file named ReusableDealingService.adprototype, alongside other files with the same extension representing the prototypes already included in the toolbox. Storing prototypes in files enables you to share them between Visual Studio users by distributing the files.
Once the file is saved, a new prototype—ReusableDealingService Endpoint—will be added automatically to the toolbox. Just drag it from the toolbox to the MarketMaker application on the diagram.
If you think about it, this mechanism is really very powerful. Not only does it facilitate the addition of the same service onto many applications, but it also allows you to define a common set of operations that all your services must implement. Imagine a getServiceVersion operation defined on a BusinessService prototype, to which you may add additional service-specific operations when the prototype is placed onto an application.
Tip: You can achieve something similar simply by copying and pasting (CTRL+C, CTRL-V) application and endpoints, though using that technique you would not have a prototype to use in other solutions or to share with other developers.
In the initial discussion, we hinted that the MarketMaker application might actually be a third-party application accessible only via a Web service URL. In that case, you could represent it on the design service in the form of an ExternalWebService that you'll find in the toolbox.
After you add an external Web service to the diagram, the Add Web Reference dialog box would appear, as shown in Figure 2-7, enabling you to specify the URL supplied by the third party.
Later in this chapter, you'll implement and deploy a DealingService, which will provide you with a URL to insert into that dialog box as though it were supplied by a third party. That's what we (the authors) did, and you might like to do the same by revisiting this section after completing the chapter.
Alternatively, you could try this out by creating a Web service in a separate running instance of Visual Studio as you would when not using these design tools and reference that service. That's not such a crazy idea because a local "dummy" version of an external service could easily be replaced with the real one later. The URLs of external Web services are not hard-coded within the application and may be specified at deployment.
To simply try out this feature outside of the context of our running example, you could use the URL for any sample Web service that you happen to find on the web. At this point, we just want you to try out the feature; we won't be asking you to build on this result.
Suppose that one way or another you have added an external DealingService onto your diagram, and suppose you did that before adding the other applications to the diagram. Wouldn't that service have made a great prototype for the same-named service on your StockBroker application?
As an alternative to adding an ExternalWebService and then creating a prototype from it, you could instead simply right-click an application—such as the StockBroker application—and choose Create Web service Endpoints from WSDL from the pop-up menu to launch the Add Web Reference dialog (refer to Figure 2-7). The result would be the same except that there will be no separate ExternalWebService on the design surface and no additional new prototype in the toolbox.
These techniques are similar to what you might have seen referred to as reverse engineering in a UML tool, but in both cases you have reverse-engineered the interfaces only, not the internal implementations. In addition, with a Web service reverse-engineered onto an existing application (just described), you will be able to go ahead and implement the service, whereas for an ExternalWebService you won't. It is "external," after all, and all you've done is reference it.
One of the key principles behind the Common Object Request Broker (CORBA) standard for distributed systems, which preceded Web services, is the separation of interfaces from implementations. The idea is that vendors can cooperate on interfaces while competing on the quality-of-service of their implementations. Therefore, reverse-engineering the interface of a third-party component and then using its prototype to front a better quality implementation seems a very logical thing to do.