TN_1108: Connecting Applications to Web Services via Class Libraries

Bill Gibson, Program Manager
Microsoft Corporation

By default, a Web service connection from a Windows or ASP.NET Web application is handled by a Web reference implemented within the root project of the application. However, in many cases, it is preferable to handle the connection deeper within the implementation architecture, from a class library or DLL. This note discusses how Web service connections are implemented, how to define connections that originate from a class library, and particularly how to safely transfer a Web reference created initially in a root project to a class library.

Applications and Web Service Connections

In Visual Studio Team Edition for Software Architects, applications are an abstraction over a set of resources, such as assemblies, configuration files, and other files that are deployed together. An application normally has a root resource, corresponding to a project in Visual Studio that defines the application.

If an application needs to access the resources of another application, it does so through endpoints. The application requiring the service has a consumer endpoint of some kind that is configured with the address of a provider endpoint. This provider endpoint is located on the application offering the services. The provider endpoint provides access to an application resource, which actually provides the implementation of the services.

In Visual Studio, a Web services connection from a project typically involves the definition of a Web reference. The Web reference generates and manages a proxy class in the root project of the consumer application. Unless static references are used, a suitable configuration entry must also be present in the Web.config or App.config file of that root project. The Web reference is created, and the proxy class is accessible only within the scope of that project. By default, when a Web service connection is created using the Application Designer, it generates the Web reference into the root project associated with the consumer application.

However, a common architectural pattern is for the root project of an application to handle only the application’s exposed interface, whether it is a user interface or programmatic interface, and to implement the business logic in one or more class libraries. This pattern separates the concerns of the interface and the business logic and increases the likelihood that the business logic implementation is reusable. In this pattern, the requirement to access another application is likely to arise in the context of the business logic implementation, which requires the creation of Web references in the appropriate class library, not in the root project.

At run time, the .NET environment establishes the configuration context for a class library from the root project of the application in which it is referenced. This means that a class library with a Web reference can be configured and connected differently in each application context in which it executes.

If you create a Web reference in a class library while working in Visual Studio, a configuration entry containing the Web service URL is added to the App.config file in the class library project. However, this entry is for reference only and is not used when the class library is referenced at run time. When you add a reference to a class library that implements a Web reference, you need to ensure that the correct configuration entry is also added to the root project’s Web.config or App.config file.

Application Designer Support for Web References from Class Libraries

Application Designer detects connections to Web services from class libraries by analyzing the configuration file of the root project. If an appropriate configuration entry exists and an associated Web reference or proxy class is found, the designer displays a consumer endpoint on the application as well as a connection to the appropriate Web service provider endpoint on the diagram.

Adding such an endpoint from the bottom up only requires that you make add a reference to a class library or DLL with a Web reference or proxy class and add the corresponding configuration file entry.

However, this scenario is not as straightforward if the connection is first established on the application diagram and the Web reference is generated into the root project, and you decide later to move it to a class library. This will be a common scenario if you use the Application Designer and System Designer to design and implement your applications and overall system architecture, and use class libraries to handle business logic.

Moving a Web Reference from Root Project to a Class Library

Moving the Web reference from the root project to a class library requires care if the system diagrams you have constructed are not to be impacted. The issue and and a simple procedure to avoid it are described below.

Visual Studio does not support moving a Web reference between projects as a single action. To move a Web reference, a new Web reference and configuration must be added to the class library project, and the old Web reference must be deleted from the root project. The outcome of these two actions is unaffected by the sequence in which you perform them.

Deleting the Web reference from the root project deletes the associated configuration entry. This action also deletes the consumer endpoint from the application definition in the application diagram. This will occur whether the application diagram is open or not at the time the Web reference is deleted. If the diagram is closed when the Web reference is deleted, the endpoint is deleted when the diagram is next opened.

When you add the equivalent Web reference to the class library and its corresponding configuration entry to the root project’s configuration file, a new consumer endpoint is added to the application. The class library must be built for this to occur. Assuming you use the same URL value, this new endpoint will be connected on the diagram to the same service as the original endpoint. If you add the new endpoint before deleting the original, you will have two endpoints and two connections to the same Web service.

Impact on System Diagrams

Regardless of the sequence you use, when you delete the original consumer endpoint from the consumer application, the Application Designer (if open or when next opened) will propagate this deletion to any open system diagrams that include the application. This deletes the corresponding endpoint(s) on the application in each system diagram, which also deletes any connection or delegation from that endpoint on those diagrams. If an affected endpoint in a system diagram is delegated, then deleting that endpoint also deletes the proxy endpoint, which will affect all other open system diagrams in which that system is used.

When the new endpoint is added to represent the Web reference in the class library, this too is reflected in all uses of that application in open system diagrams, but it will not be connected or delegated even if the original endpoint was. The system is unaware of the purpose of the new endpoint and cannot tell how it should be connected. This behavior is consistent with normal use of the system diagram, which is not intended to reflect configuration changes to the application diagram automatically. Applications in a system diagram can be configured differently from their configuration in the application diagram or other system diagrams

At this point, you could modify the affected system diagram to reconnect the endpoints or re-add proxy endpoints. As a one-off requirement, this might not be too onerous. However, if you adopt the pattern of making Web service connections via class libraries, then many connections and delegations might be impacted as you migrate all the Web services consumer endpoints from root projects to class libraries when you come to implement the applications. In a worst case scenario, every single connection in every system diagram in a complex architecture could be deleted and need to be re-added.

Keep ‘em Connected

However, there is a simple way to ensure that system diagrams are not impacted when you migrate endpoints, and that connections and delegations are not broken:

  • Add the replacement Web reference to a referenced class library and build it. Add the appropriate configuration entry to the root project’s configuration file. Two endpoints will be present and connected to the same Web service on the application diagram.

  • Close all system diagrams that include the consumer application.

  • From the application diagram, make a note of the name used for the original consumer endpoint. You can find this on the Properties window or by choosing Show Label on the endpoint on the diagram.

  • Delete the original consumer endpoint on the diagram or remove the corresponding Web reference from the Solution Explorer.

  • Rename the newly-added consumer endpoint using the same name as the original consumer endpoint. You cannot do this until the original endpoint is deleted.

When you next open any system diagram that references the consumer application, it will detect no change, so there will be no change to consumer endpoints, which remain connected or delegated as before. It is impotrant to close the system diagrams before you delete the original endpoint and to use the same name for the new endpoint. System references to application endpoints are name-based.

For further discussion about applications and their representation in the Application Designer, see Understanding Applications and Application Diagram, and about the role of class libraries, see Why Class Libraries are Not Supported on the Application Diagram.

Summary

The Application Designer is able to represent Web service connections implemented by class libraries and DLLs referenced from an application. A simple procedure should be used when migrating a Web reference from a root project in an application to a class library. This procedure avoids unecessarily deleting connections and proxy endpoints from systems.