Cenni preliminari sulla creazione di endpoint

Tutte le comunicazioni con un servizio Windows Communication Foundation (WCF) vengono eseguite tramite gli endpoint del servizio. Gli endpoint forniscono ai client l'accesso alla funzionalità offerta da un servizio WCF. Questa sezione descrive la struttura di un endpoint e viene illustrato come definire un endpoint nella configurazione e nel codice.

Struttura di un endpoint

Ogni endpoint contiene un indirizzo che indica dove individuare l'endpoint, un'associazione che specifica in che modo un client può comunicare con l'endpoint e un contratto che identifica i metodi disponibili.

  • Indirizzo. L'indirizzo identifica in modo univoco l'endpoint e comunica ai potenziali utenti l'ubicazione del servizio. È rappresentato nel modello a oggetti WCF dall'indirizzo EndpointAddress che contiene un URI (Uniform Resource Identifier) e proprietà dell'indirizzo che includono un'identità, alcuni elementi WSDL (Web Services Description Language) e una raccolta di intestazioni facoltative. Le intestazioni facoltative forniscono dettagli aggiuntivi sull'indirizzo per identificare o interagire con l'endpoint. Per altre informazioni, vedere Specifica di un indirizzo endpoint.

  • Binding. L'associazione specifica la modalità di comunicazione con l'endpoint. L'associazione specifica in che modo l'endpoint comunica con il mondo, incluso il protocollo di trasporto da usare (ad esempio, TCP o HTTP), il tipo di codifica da usare per i messaggi (ad esempio, testo o binaria) e i requisiti di sicurezza necessari (ad esempio, Secure Sockets Layer [SSL] o sicurezza dei messaggi SOAP). Per altre informazioni, vedere Uso di binding per configurare servizi e client.

  • Contratto di servizio. Il contratto di servizio delinea la funzionalità che l'endpoint espone al client. Un contratto specifica le operazioni che un client può richiamare, il modulo del messaggio e il tipo di parametri o dati di input necessari per chiamare l'operazione e il tipo di elaborazione o messaggio di risposta che il client può aspettarsi. Tre tipi di contratti di base corrispondono a modelli di scambio dei messaggi (MEP, Message Exchange Pattern) di base: datagramma (unidirezionale), request/reply e duplex (bidirezionale). Il contratto di servizio può inoltre usare contratti dati e contratti di messaggio per richiedere tipi di dati e formati di messaggio specifici al momento dell'accesso. Per altre informazioni su come definire un contratto di servizio, vedere Progettazione di contratti di servizio. Per ricevere messaggi dal servizio in un modello di scambio dei messaggi (MEP) duplex, è possibile che un client debba implementare un contratto definito dal servizio, detto contratto di callback. Per altre informazioni, vedere Servizi duplex.

L'endpoint per un servizio può essere specificato in modo imperativo mediante l'uso di codice oppure in modo dichiarativo mediante la configurazione. Se non è specificato alcun endpoint, il runtime ne fornisce di predefiniti aggiungendone uno per ogni indirizzo di base per ciascun contratto di servizio implementato dal servizio. In genere definire endpoint nel codice non è pratico in quanto le associazioni e gli indirizzi di un servizio distribuito sono solitamente diversi da quelli usati durante lo sviluppo del servizio. In genere è più pratico definire endpoint di servizio mediante la configurazione piuttosto che mediante codice. Se le informazioni sull'associazione e sull'indirizzo non vengono incluse nel codice, tali dati possono essere modificati senza dover compilare e distribuire nuovamente l'applicazione.

Nota

Quando si aggiunge un endpoint di servizio che esegue la rappresentazione, è necessario usare uno dei metodi AddServiceEndpoint o il metodo GetContract(Type, Type) per caricare correttamente il contratto in un nuovo oggetto ServiceDescription.

Definizione di endpoint nel codice

Nell'esempio riportato di seguito viene illustrato come specificare un endpoint nel codice.

  • Definire un contratto per un tipo di servizio IEcho che accetta il nome e l'eco di un utente con la risposta "Hello <name>!".

  • Implementare un servizio Echo del tipo definito dal contratto IEcho.

  • Specificare un indirizzo endpoint di http://localhost:8000/Echo per il servizio.

  • Configurare il servizio Echo usando un'associazione WSHttpBinding.

namespace Echo
{
   // Define the contract for the IEcho service
   [ServiceContract]
   public interface IEcho
   {
       [OperationContract]
       String Hello(string name)
   }

   // Create an Echo service that implements IEcho contract
   class Echo : IEcho
   {
      public string Hello(string name)
      {
         return "Hello" + name + "!";
      }
      public static void Main ()
      {
          //Specify the base address for Echo service.
          Uri echoUri = new Uri("http://localhost:8000/");

          //Create a ServiceHost for the Echo service.
          ServiceHost serviceHost = new ServiceHost(typeof(Echo),echoUri);

          // Use a predefined WSHttpBinding to configure the service.
          WSHttpBinding binding = new WSHttpBinding();

          // Add the endpoint for this service to the service host.
          serviceHost.AddServiceEndpoint(
             typeof(IEcho),
             binding,
             echoUri
           );

          // Open the service host to run it.
          serviceHost.Open();
     }
  }
}
' Define the contract for the IEcho service
    <ServiceContract()> _
    Public Interface IEcho
        <OperationContract()> _
        Function Hello(ByVal name As String) As String
    End Interface

' Create an Echo service that implements IEcho contract
    Public Class Echo
        Implements IEcho
        Public Function Hello(ByVal name As String) As String _
 Implements ICalculator.Hello
            Dim result As String = "Hello" + name + "!"
            Return result
        End Function

' Specify the base address for Echo service.
Dim echoUri As Uri = New Uri("http://localhost:8000/")

' Create a ServiceHost for the Echo service.
Dim svcHost As ServiceHost = New ServiceHost(GetType(HelloWorld), echoUri)

' Use a predefined WSHttpBinding to configure the service.
Dim binding As New WSHttpBinding()

' Add the endpoint for this service to the service host.
serviceHost.AddServiceEndpoint(GetType(IEcho), binding, echoUri)

' Open the service host to run it.
serviceHost.Open()

Nota

L'host del servizio viene creato con un indirizzo di base. Il resto dell'indirizzo, relativo all'indirizzo di base, viene quindi specificato come parte di un endpoint. Questo partizionamento dell'indirizzo consente a più endpoint di essere definiti in modo più appropriato per i servizi presenti in un host.

Nota

Le proprietà di ServiceDescription nell'applicazione del servizio non devono essere modificate dopo la chiamata al metodo OnOpening su ServiceHostBase. Se vengono modificati dopo questo punto, alcuni membri, ad esempio la proprietà Credentials e i metodi AddServiceEndpoint su ServiceHostBase e ServiceHost, generano un'eccezione. Altri consentono la modifica, ma il risultato è indefinito.

Analogamente, sul client i valori ServiceEndpoint non devono essere modificati dopo la chiamata a OnOpening su ChannelFactory. Se viene modificata dopo questo punto, la proprietà Credentials genera un'eccezione. Gli altri valori della descrizione client possono essere modificati senza errore, ma il risultato è indefinito.

Per il servizio o per il client, è consigliabile modificare la descrizione prima di chiamare Open.

Definizione di endpoint nella configurazione

Durante la creazione di un'applicazione è spesso necessario rimettere le decisioni all'amministratore che distribuisce l'applicazione. Spesso non è possibile prevedere, ad esempio, quale sarà l'indirizzo (URI) di un servizio. Anziché inserire un indirizzo nel codice, è preferibile consentire che questa operazione venga eseguita da un amministratore dopo la creazione del servizio. Questa flessibilità viene realizzata attraverso la configurazione. Per informazioni dettagliate, vedere Configurazione dei servizi.

Nota

Usare lo Strumento ServiceModel Metadata Utility (Svcutil.exe) con il passaggio /config:nome file[,nome file] per creare rapidamente i file di configurazione.

Uso di endpoint predefiniti

Se non è specificato alcun endpoint nel codice o nella configurazione, il runtime ne fornisce di predefiniti aggiungendone uno per ogni indirizzo di base per ciascun contratto di servizio implementato dal servizio. L'indirizzo di base può essere specificato nel codice o nella configurazione e gli endpoint predefiniti vengono aggiunti quando viene chiamato Open() in ServiceHost. Questo esempio è identico a quello della sezione precedente, ma poiché non è stato specificato alcun endpoint, vengono aggiunti gli endpoint predefiniti.

namespace Echo
{
   // Define the contract for the IEcho service
   [ServiceContract]
   public interface IEcho
   {
       [OperationContract]
       String Hello(string name)
   }

   // Create an Echo service that implements IEcho contract
   public class Echo : IEcho
   {
      public string Hello(string name)
      {
         return "Hello" + name + "!";
      }
      public static void Main ()
      {
          //Specify the base address for Echo service.
          Uri echoUri = new Uri("http://localhost:8000/");

          //Create a ServiceHost for the Echo service.
          ServiceHost serviceHost = new ServiceHost(typeof(Echo),echoUri);

          // Open the service host to run it. Default endpoints
          // are added when the service is opened.
          serviceHost.Open();
     }
  }
}
' Define the contract for the IEcho service
    <ServiceContract()> _
    Public Interface IEcho
        <OperationContract()> _
        Function Hello(ByVal name As String) As String
    End Interface

' Create an Echo service that implements IEcho contract
    Public Class Echo
        Implements IEcho
        Public Function Hello(ByVal name As String) As String _
 Implements ICalculator.Hello
            Dim result As String = "Hello" + name + "!"
            Return result
        End Function

' Specify the base address for Echo service.
Dim echoUri As Uri = New Uri("http://localhost:8000/")

' Open the service host to run it. Default endpoints
' are added when the service is opened.
serviceHost.Open()

Se vengono forniti endpoint in modo esplicito, è comunque possibile aggiungere gli endpoint predefiniti chiamando AddDefaultEndpoints su ServiceHost prima di chiamare Open. Per altre informazioni sugli endpoint predefiniti, vedere Configurazione semplificata e Configurazione semplificata per servizi WCF.

Vedi anche