BrainDump
  Home arrow BrainDump arrow Page 2 - Handling Multiple Contracts with Indigo
ASP Free Forums 
.NET  
ASP  
ASP Code  
ASP.NET  
ASP.NET Code  
BrainDump  
C#  
Code Examples  
Database  
Database Code  
IIS  
Microsoft Access  
MS SQL Server  
Visual Basic.NET  
Windows Scripting  
Windows Security  
XML  
ASP Web Hosting  
ASP.NET Web Hosting 
Mobile Linux 
App Generation ROI 
Windows Web Hosting
 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
BRAINDUMP

Handling Multiple Contracts with Indigo
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 5 stars5 stars5 stars5 stars5 stars / 1
    2008-05-15

    Table of Contents:
  • Handling Multiple Contracts with Indigo
  • Proxy Generation for Multiple Contracts and Endpoints
  • Sharing Service Contracts
  • Summary

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Handling Multiple Contracts with Indigo - Proxy Generation for Multiple Contracts and Endpoints


    (Page 2 of 4 )

    Adding a service reference generates the proxy and configuration settings necessary to access a particular service. If the service implements multiple contracts, a proxy type is generated for each contract. For example, in this lab when you add a service reference to ServiceA in the ExternalClient project, the following proxies are generated--one for IServiceA, another for IAdmin:

      public partial class ServiceAClient :
     
    System.ServiceModel.ClientBase <ExternalClient.ServiceA.IServiceA>,
     
    ExternalClient.ServiceA.IServiceA

      public partial class AdminClient :
      System.ServiceModel.ClientBase <ExternalClient.ServiceA.IAdmin>,
     
    ExternalClient.ServiceA.IAdmin

    Likewise, when you add a service reference toServiceB a proxy is generated for both contracts:IServiceBandIAdmin.

    In theory, because theIAdminservice contract is the same for both services, they could share a proxy, but SvcUtil generates proxy types for all contracts and has no knowledge of the code you have already generated.

    In addition to generating proxies, SvcUtil generates the configuration necessary for each endpoint exposed by each service. SvcUtil always provides a name for each<endpoint>element, so you can specify the correct endpoint to use by name when constructing each proxy. Example 1-27 shows the client endpoints generated forServiceAandServiceB; the endpoints used in the lab for theExternalClient are shown in bold.

    Example 1-27. Client endpoints generated for ServiceA and ServiceB

    <client>
     
    <endpoint address="net.tcp://localhost:9000/Admin" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IAdmin" contract="ExternalClient.ServiceA.IAdmin" name="NetTcpBinding_IAdmin" />
     
    <endpoint address="http://localhost:8000/ServiceA" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceA" contract="ExternalClient.ServiceA.IServiceA" name="BasicHttpBinding_IServiceA" />
      <endpoint address="net.tcp://localhost:9000/ServiceA" binding="netTcpBinding" bindingConfiguration="NetTcpBinding_IServiceA"
    contract="ExternalClient.ServiceA.IServiceA"
    name="NetTcpBinding_IServiceA" />
     
    <endpoint address="net.pipe://localhost/Admin" binding="netNamedPipeBinding"
    bindingConfiguration="NetNamedPipeBinding_IAdmin" contract="ExternalClient.ServiceB.IAdmin" name="NetNamedPipeBinding_IAdmin" />
     
    <endpoint address="http://localhost:8001/ServiceB" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_IServiceB" contract="ExternalClient.ServiceB.IServiceB" name="BasicHttpBinding_IServiceB" />
      <endpoint address="net.pipe://localhost/ServiceB" binding="netNamedPipeBinding" bindingConfiguration="NetNamedPipeBinding_IServiceB" contract="ExternalClient.ServiceB.IServiceB" name="NetNamedPipeBinding_IServiceB" /> </client>

    Although the client may not have network rights to invoke the TCP or named pipe endpoints, these endpoints are still part of the service description (WSDL) and therefore are visible to the client.

    Recall that a WSDL document is created for each service type. Thus, to prevent remote clients from seeing internal endpoints that they should not access, you can create different service types for internal and external use--funneling them to the same implementation code. On external service types, you can expose endpoints only for supported contracts over HTTP. For internal service types, you can expose internal contracts and TCP and named pipes endpoints. To modify the lab in support of this scenario, you might see the following service types:

      public class ServiceA : IServiceA {...}
      public class InternalServiceA : IServiceA, IAdmin {...}
     
    public class ServiceB : IServiceB {...}
      public class InternalServiceB : IServiceB, IAdmin {...}

    In the host configuration, each service type would be defined in a separate<service>element, exposing only the required endpoints. A compressed view of the required<service>elements is shown here:

      <service name="BusinessServices.ServiceA" ...> 
      <service name="BusinessServices.InternalServiceA" ...>
      <service name="BusinessServices.ServiceB" ...>
      <service name="BusinessServices.InternalServiceB" ...>

    The following sample illustrates this scenario: <YourLearningWCFPath>\Samples\ServiceContracts\ MultiContractServices_UniqueServiceTypes.

    Proxy Initialization and Lifetime

    Each client proxy opens a communication channel to invoke a service endpoint. The proxy can be programmatically initialized in code or declaratively initialized per the client's service model configuration. If there is only one endpoint configured for a particular service contract, there is no need to specify an endpoint configuration name to the constructor of the channel factory or proxy.

    When you useChannelFactory<T>to create the channel from the default endpoint, you pass empty quotes to the constructor. This example expects that only one endpoint is configured forIServiceA:

      ChannelFactory<IServiceA> factoryA = new
      ChannelFactory<IServiceA>("");
      m_proxyA = factoryA.CreateChannel();

    Generated proxies provide a default constructor to achieve the same result:

      m_proxyA = new ExternalClient.ServiceA.ServiceAClient();

    On the other hand, when multiple endpoints exist for the same contract, you must provide a configuration name as shown here forChannelFactory<T>and for a generated proxy:

      ChannelFactory<BusinessServiceContracts. IServiceA> factoryA = new 
      ChannelFactory<BusinessServiceContracts. IServiceA>("BasicHttpBinding_IServiceA");
      proxyA = factoryA.CreateChannel();

      m_proxyA = new
      ExternalClient.ServiceA.ServiceAClient("BasicHttpBinding_IServiceA");

    In either case, the lifetime of the communication channel is controlled by the proxy reference. If the client application intends to invoke the service endpoint repeatedly, it is better not to recreate the proxy each time an operation is invoked. Instead, the proxy should be scoped to the lifetime of the application.

    When the application is shutting down, you should close the proxy to speed up the release of resources. When you are working with a channel factory to create the proxy reference, you must cast toICommunicationObjectin order to call itsClose()method (see Example1-24). The equivalent inline steps would be as follows:

      ICommunicationObject proxyACommunication = m_proxyA as ICommunicationObject;
      ...
      proxyACommunication.Close();

    This step is required because the channel factory returns a reference to the service contract, which doesn't expose aClose()method. Still, the underlying object is aCommunicationObjectthat implementsICommunicationObject.

    Proxies generated with SvcUtil include code to wrap the inner communication channel. In addition, each generated proxy type implementsICommunicationObjectdirectly, and thus provides aClose()method.

    Be aware that the channel stack beneath the proxy reference can be put into a faulted or invalid state. For example, if the service is no longer available, or if the service throws an exception, or if a timeout occurs at either end. In Chapter 8, Ill discuss exception handling.

    Another point to note is that the lifetime of the communication channel should not be confused with the lifetime of the service instance instantiated by the host to handle a request. In fact, a different service instance may be allocated for every call even if the client uses the same channel. This behavior is controlled by the service. Service instancing and throttling behaviors are covered in Chapter 5.

    More BrainDump Articles
    More By O'Reilly Media


       · This article is an excerpt from the book "Learning WCF A Hands-on Guide," published...
     

    Buy this book now. This article is excerpted from chapter 1 of the book Learning WCF A Hands-on Guide, written by Michele Leroux Bustamante (O'Reilly, 2007; ISBN: 0596101627). Check it out today at your favorite bookstore. Buy this book now.

    BRAINDUMP ARTICLES

    - Internet Explorer 8 Review
    - Nilpo`s Top Windows Add-Ons
    - Beginning Silverlight 2.0 Development using ...
    - Fixing Vista`s Troubles
    - Preparing Windows Images for Mass Deployment
    - The Trouble With Vista
    - Slipstreamed and Unattended Windows Installa...
    - Microsoft Office SharePoint Server
    - Microsoft Office SharePoint Designer
    - Microsoft Windows SharePoint Services 3.0
    - Microsoft Live Mesh Overview
    - XAML Brushes and Silverlight
    - Silverlight and XAML Basics
    - Immortal XP
    - XAML Basics





    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway
    Stay green...Green IT