Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 1
Lógica de Negócio com WCF
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
O que é?
•Uma tecnologia para suportar o desenvolvimento de
aplicações distribuídas orientadas aos serviços, não
apenas web services
•Uma única tecnologia para substituir várias
tecnologias diferentes: Enterprise Services, MSMQ,
DCOM/.Net Remoting
serviço
endpoint
endpoint
endpoint
serviço
endpoint
endpoint
endpoint
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 3
Serviços e endpoints
Serviços e clientes comunicam enviando mensagens
para endpoints
hospedeiro
serviço
endpoint
endpoint
endpoint
cliente
endpoint
mensagens
Pode ser qualquer processo
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
ABC da comunicação
Os clientes necessitam de saber a seguinte informação para comunicarem com um endpoint:
Address– é a indicação da localização na rede para onde devem ser
enviadas as menssagens destinadas ao endpoint (exemplos: http://localhost/Servico, net.tcp://servidor/Servico)
Binding– define características dos canais a serem usados para
comunicar com o endpoint. Um binding é um conjunto de elementos de binding para especificar os protocolos de transporte (HTTP, TCP, MSMQ, Named pipes,...) e restrições de segurança e transacções. Existem pré-definidos vários bindings (basicHttpBinding, wsHttpBinding, ...)
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 5
ABC da comunicação
Os serviços podem opcionalmente incluir um endpoint designado
MetaDataExchange (MEX) que os clientes podem usar para obter os
ABCs dos endpoints do serviço.
O visual studio 2008 usa esta opção quando se escolhe Add Service
Reference num projecto e a ferramenta svcutil.exe também a usa. Em
ambos os casos, a informação retornada é usada para criar um ficheiro
de configuração da aplicação (app.config) e
uma classe com a definição de um proxy que permite ao cliente aceder
ao endpoint e um ficheiro de configuração da aplicação (app.config)
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
Um primeiro serviço
O contrato:
[ServiceContract]
public interface IServicoContas {
[OperationContract]
float obterSaldo(int numero);
[OperationContract]
void alterarSaldo(int numero, float s);
}
Podem ter propriedades diferentes
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 7
Um primeiro serviço
O serviço:
public class ServicoContas : IServicoContas
{
public float obterSaldo(int numero) {
...
}
public void alterarSaldo(int numero, float s) {
...
}
}
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
Um primeiro serviço
O hospedeiro (self hosting):
public class Servico
{
public static void Main(string[] args) {
ServiceHost host =
new ServiceHost(typeof(ServicoContas),
new Uri("http://localhost:8000/Exemplo1"));
host.AddServiceEndpoint(typeof(IServicoContas),
new BasicHttpBinding(),"");
host.Open();
Console.WriteLine("Serviço iniciado. Enter para terminar");
Console.ReadLine();
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 9
Um primeiro serviço
O hospedeiro (self hosting) usando código e app.config:
public class Servico
{
public static void Main(string[] args) {
ServiceHost host = new ServiceHost(typeof(ServicoContas));
host.Open();
Console.WriteLine("Serviço iniciado. Enter para terminar");
Console.ReadLine();
host.Close();
}
}
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
Um primeiro serviço
O hospedeiro usando código e app.config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services> <service name="Exemplo1.ServicoContas"> <host> <baseAddresses> <add baseAddress="http://localhost:8000/Exemplo1"/> </baseAddresses> </host> <endpoint address="" binding = "basicHttpBinding" contract="Exemplo1.IServicoContas"/> </service> </services> </system.serviceModel> </configuration>Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 11
Um primeiro serviço
Serviço com MEX configurado por código
public class Servico {
public static void Main(string[] args) {
ServiceHost host = new ServiceHost(typeof(ServicoContas));
ServiceMetadataBehavior b = new ServiceMetadataBehavior(); b.HttpGetEnabled = true; host.Description.Behaviors.Add(b); host.AddServiceEndpoint( typeof(IMetadataExchange), MetadataExchangeBindings.CreateMexHttpBinding(), "mex"); host.Open(); ...
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
Um primeiro serviço
Serviço com MEX configurado em app.config
<?xml version="1.0" encoding="utf-8" ?> <configuration>
<system.serviceModel> <services>
<service name="Exemplo1.ServicoContas" behaviorConfiguration="sb">
<host>
<baseAddresses>
<add baseAddress="http://localhost:8000/Exemplo1"/> </baseAddresses>
</host>
<endpoint address="" binding ="basicHttpBinding" contract="Exemplo1.IServicoContas"/>
<endpoint address = "mex" binding = "mexHttpBinding" contract = "IMetadataExchange"/>
</service> </services> <behaviors> <serviceBehaviors> <behavior name="sb"> <serviceMetadata httpGetEnabled="True"/> </behavior>
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 13
Um cliente só com código
[ServiceContract]
public interface IServicoContas { [OperationContract]
float obterSaldo(int numero); [OperationContract]
void alterarSaldo(int numero, float s); }
class Cliente {
static void Main(string[] args) {
ChannelFactory<IServicoContas>
servico = new ChannelFactory<IServicoContas>( new BasicHttpBinding(),
new EndpointAddress(
"http://localhost:8000/Exemplo1")); IServicoContas endpt = servico.CreateChannel(); float s = endpt.obterSaldo(1);
Console.WriteLine("Saldo conta 1 = {0}", s); ...
} }
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
Um cliente configurado com app.config
[ServiceContract]
public interface IServicoContas { [OperationContract]
float obterSaldo(int numero); [OperationContract]
void alterarSaldo(int numero, float s); }
class Cliente {
static void Main(string[] args) {
ChannelFactory<IServicoContas>
servico = new ChannelFactory<IServicoContas>( "clienteServicoContas");
IServicoContas endpt = servico.CreateChannel(); float s = endpt.obterSaldo(1);
Console.WriteLine("Saldo conta 1 = {0}", s); ...
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 15
Um cliente configurado com app.config
<?xml version="1.0" encoding="utf-8" ?> <configuration>
<system.serviceModel>
<client>
<endpoint name="clienteServicoContas“
address ="http://localhost:8000/Exemplo1“ binding="basicHttpBinding" contract="IServicoContas"/> </client> </system.serviceModel> </configuration>
WCF
WCF
–
–
Introdu
Introdu
ç
ç
ão
ão
Um cliente usando a opção Add Service Reference do Visual Studio 2008
using ExemploClienteASR.ServiceReference1; namespace Exemplo1ClienteASR
{
class Program {
static void Main(string[] args) { ServicoContasClient proxy = new ServicoContasClient(); float s = proxy.obterSaldo(1); Console.WriteLine("Saldo conta 1 = {0}", s); s *= 2; proxy.alterarSaldo(1, s); proxy.Close(); } } }
O VS usou o MEX do serviço para criar o namespace <nome
projecto>.ServiceReference1 no qual é implementada a classe proxy de nome <nome do contrato>Client(*). Também é gerado o ficheiro app.config (ou web.config) com o nó <system.serviceModel> apropriado . (*)Na verdade, <nome do contrato> pode não coincidir com o nome do contrato. Pode ter sido retirado o I
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 17
Qualquer processo managed pode servir como hospedeiro.
Já vimos como hospedar um serviço numa aplicação .net (self hosting)
Para além deste tipo de hospedagem, são ainda possíveis:
1.
Hospedagem em IIS
2.
Hospedagem num serviço windows
3.
Hospedagem em Windows Activation Server (WAS)
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem em IIS
Para basicHttpBinding, wsHttpBindig e wsDualHttpBinding, é possível
hospedar os serviços no IIS.
Procedimento:
1.
Criar uma aplicação virtual no IIS para alojar o serviço
2.
Criar um ficheiro com a extensão .svc para definir a
implementação do serviço.
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 19
Hospedagem em IIS
Em ServicoContas.cs:
namespace Exemplo1IISManual { ... [ServiceContract]public interface IServicoContas {
[OperationContract] float obterSaldo(int numero); [OperationContract]
void alterarSaldo(int numero, float s); }
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem em IIS
Em ServicoContas.cs:
public class ServicoContas: IServicoContas {
public float obterSaldo(int numero) {
... }
public void alterarSaldo(int numero, float s) {
... } }
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 21
Hospedagem em IIS
Em ServicoContas.svc:
<%@ServiceHost Language="C#" Service="Exemplo1IISManual.ServicoContas" %> Em web.config: <?xml version="1.0"?> <configuration> <system.serviceModel> <services> <service name="Exemplo1IISManual.ServicoContas“ behaviorConfiguration="ServicoContasBehavior"> <endpoint address="" binding="basicHttpBinding"
contract="Exemplo1IISManual.IServicoContas"> </endpoint>
<endpoint address="mex" binding="mexHttpBinding"
contract="IMetadataExchange"/> </service> </services>
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem em IIS
Em web.config: <behaviors> <serviceBehaviors> <behavior name="ServicoContasBehavior"> <serviceMetadata httpGetEnabled="true"/> <serviceDebug includeExceptionDetailInFaults="false"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 23
Hospedagem em IIS
Em alternativa poderiamos ter em ServicoContas.svc:
1. <%@ServiceHost Language="C#" Service="Exemplo1IISManual.ServicoContas“ CodeBehind="~/App_Code/ServicoContas.cs" %> Neste caso na primeira utilização o fichiero ServicoContas.cs seria compilado
2. <%@ServiceHost Language="C#" Service="Exemplo1IISManual.ServicoContas" %> Código do serviço
Nesta caso o código seria compilado por cada invocação do serviço
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem wm WAS
Para Windows Vista e Windows Server 2008, é possível hospedagem em
Windows Process Activation Services (WAS), o qual suporta multiplos
protocolos ao nível de transporte (HTTP, net.tcp, net.pipe, net.msmq,...).
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 25
Hospedagem em Managed Windows Service
Os MWS são controlados pelo Service Control Manager (SCM) e
administrados através de Microsoft Management Console (MMC), ou de
outras ferramentas que utilizem a as APIs Windows Management
Instrumentation (WMI) e SCM.
O VS2008 tem uma opção de projecto para MWS
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem em Managed Windows Service
namespace Exemplo1MWS { [ServiceContract]
public interface IServicoContas {
[OperationContract] float obterSaldo(int numero); [OperationContract]
void alterarSaldo(int numero, float s); }
public class ServicoContas : IServicoContas { public float obterSaldo(int numero) { }
public void alterarSaldo(int numero, float s) { }
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 27
Hospedagem em Managed Windows Service
[RunInstaller(true)]// auto-instalação// O nome pode ser diferente, pois o atributo é que conta public class ProjectInstaller : Installer // installutil.exe. {
private ServiceProcessInstaller pi; private ServiceInstaller si; public ProjectInstaller() { pi = new ServiceProcessInstaller(); pi.Account = ServiceAccount.LocalSystem; si = new ServiceInstaller(); si.ServiceName = "Exemplo1MWS"; si.Description = "Teste de WCF";
Installers.Add(pi); // informação sobre o processo a instalar Installers.Add(si); // descrição do serviço a instalar
} }
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem em Managed Windows Service
public partial class ServicoMWS: ServiceBase { public ServicoMWS() { InitializeComponent(); } protected override void OnStart(string[] args) {
ServiceHost host = new ServiceHost(typeof(ServicoContas)); host.Open(); ServiceEndpoint ep = host.Description.Endpoints[0]; EventLog.WriteEntry(ep.Contract.Name+ " iniciado. Endpoint: "+ ep.Address+ " Binding "+ ep.Binding.Name,
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 29
Hospedagem em Managed Windows Service
protected override void OnStop() { EventLog.WriteEntry("Exemplo1MWS terminado", System.Diagnostics.EventLogEntryType.Information); } } }
WCF
WCF
–
–
Hospedagem
Hospedagem
Hospedagem em Managed Windows Service
static class Program {
static void Main() {
ServiceBase[] ServicesToRun; ServicesToRun = new ServiceBase[]
{ new ServicoMWS() }; ServiceBase.Run(ServicesToRun); } }
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 31
Endereços de serviços e endpoints.
Dado que um serviço é uma colecção de endpoints, o endereço do serviço
pode servir de base para esquemas de endereçamento relativo dos endpoints
(mas não é obrigatório).
Exemplo:
... <host> <baseAddresses> <add baseAddress="http://localhost:8000/Exemplo1"/> </baseAddresses> </host> <endpoint address="" binding = "basicHttpBinding" contract="Exemplo1.IServicoContas"/> <endpoint address = "mex"binding = "mexHttpBinding" contract = "IMetadataExchange"/> Endereço: http://localhost:8000/Exemplo1 Endereço: http://localhost:8000/Exemplo1/mex
WCF
WCF
–
–
Hospedagem
Hospedagem
Endereços de serviços e endpoints.
Podem existir vários endereços do serviço, mas apenas um por cada esquema de URI. Os conflitos nos endpoints que usem os mesmos endereços relativos são resolvidos pelos bindings.
Exemplo:
... <host> <baseAddresses> <add baseAddress="http://localhost:8000/Exemplo1"/> <add baseAddress=“net.tcp://localhost:8001/Exemplo1"/> </baseAddresses> </host> <endpoint address=“ep" binding = "basicHttpBinding" contract="Exemplo1.IServicoContas"/> Endereço: http://localhost:8000/Exemplo1/epArquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 33
Hospedagem de multiplos serviços no mesmo processo:
WCF
WCF
–
–
Contratos
Contratos
Web Services Description Language (WSDL) é um formato XML para
descrever serviços (de rede) como um con junto de ports (endpoints) que
operam sobre mensagens as quais contêm informação orientada para os
procedimentos ou informação orientada para os documentos.
As operações e mensagens são definidas de forma abstracta e associadas
(bind) a um protocolo concreto de rede e a um fromato concreto de
mensagem de forma a definirem um endpoint.
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 35
Elemento Descrição
Type Definições de tipos de dados usados para descrever a troca de mensagens (em regra XSD)
Message Definição abstracta dos dados a transmitir. Uma mensagem consiste
em várias componentes lógicas com definição num sistema de tipos (Type)
Operation O nome e descrição de uma acção suportada pelo serviço que expõe
a parte da capacidade e funcionalidade de um endpoint
PortType Um conjunto (com nome) de operações relacionadas e mensagens
abstractas envolvidas. Um endpoint implementa um PortType (service contract)
Binding Define o formato das mensagens e detalhes dos protocolos de
comunicação definidos para um PortTypeparticular
Port Especifica um endpoint particular indicando um endereço particular para um Binding
Service Define um conjunto de Ports relacionados
Os contratos são uma forma simples de associar elementos CLR a descrições WSDL
WCF
WCF
–
–
Contratos
Contratos
[ServiceContract]
public interface IServicoContas {
[OperationContract] float obterSaldo(int numero); [OperationContract]
void alterarSaldo(int numero, float s); }
public class ServicoContas : IServicoContas { public float obterSaldo(int numero) { }
public void alterarSaldo(int numero, float s) { }
} ...<service name="Exemplo1IISManual.ServicoContas“
behaviorConfiguration="ServicoContasBehavior"> <endpoint address="" binding="basicHttpBinding"
contract="Exemplo1IISManual.IServicoContas"> </endpoint>
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 37 <?xml version="1.0" encoding="utf-8" ?>
<wsdl:definitions name="ServicoContas" targetNamespace="http://tempuri.org/" xmlns:wsdl= ... > <wsdl:types> <xsd:schema targetNamespace="http://tempuri.org/Imports"> <xsd:import schemaLocation=.... /> ... </xsd:schema> </wsdl:types> <wsdl:message name="IServicoContas_obterSaldo_InputMessage"> <wsdl:part name="parameters" element="tns:obterSaldo" /> </wsdl:message>
<wsdl:message name="IServicoContas_obterSaldo_OutputMessage"> <wsdl:part name="parameters" element="tns:obterSaldoResponse" /> </wsdl:message> ... <wsdl:portType name="IServicoContas"> <wsdl:operation name="obterSaldo"> <wsdl:input wsaw:Action="http://tempuri.org/IServicoContas/obterSaldo“ message="tns:IServicoContas_obterSaldo_InputMessage" /> <wsdl:output wsaw:Action="http://tempuri.org/IServicoContas/obterSaldoResponse“ message="tns:IServicoContas_obterSaldo_OutputMessage" /> </wsdl:operation> ... </wsdl:portType>
WCF
WCF
–
–
Contratos
Contratos
<wsdl:binding name="BasicHttpBinding_IServicoContas" type="tns:IServicoContas"> <soap:binding transport="http://schemas.xmlsoap.org/soap/http" />
<wsdl:operation name="obterSaldo">
<soap:operation soapAction="http://tempuri.org/IServicoContas/obterSaldo" style="document" /> <wsdl:input> <soap:body use="literal" /> </wsdl:input> <wsdl:output> <soap:body use="literal" /> </wsdl:output> </wsdl:operation> </wsdl:binding> <wsdl:service name="ServicoContas">
<wsdl:port name="BasicHttpBinding_IServicoContas" binding="tns:BasicHttpBinding_IServicoContas"> <soap:address location=
"http://sisad_mobile.ssic.deetc.win.isel.ipl.pt/Exemplo1IISManual/ServicoContas.svc" /> </wsdl:port>
</wsdl:service> </wsdl:definitions>
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 39
Service contracts:
[ServiceContract]
public interface IServicoContas
{
[OperationContract]
float obterSaldo(int numero);
[OperationContract]
void alterarSaldo(int numero, float s);
void naoObjectoDoContrato();
}
WCF
WCF
–
–
Contratos
Contratos
Service contracts:
Propriedades de ServiceContract:Name– controla a propriedade name no elemento <portType> do WSDL (por omissão, o nome da interface do contrato)
Namespace– idem, mas para a propriedade namespace (por omissão
http://tempuri.org)
SessionMode– indica se o contrato exige um binding que suporte sessões (por
omissão, false)
CallbackContract– especifica o contrato (tipo .NET) de retorno numa
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 41 Propriedades de OperationContract:
Name– especifica o nome associado ao elementowsdl:operation name na definição de PortType. Por omissão, o nome do método.
Action– especifica a acção (elementowsdl:input wsaw:Action na definição de
PortType) que identifica unicamente esta operação. Por omissão a concatenação do namespace do contrato, do nome do contrato (interface) do nome da operação e da string “Response” se a mensagem for uma resposta. Pode ser ‘*’ para redireccionar para esta operação todas as mensagens recebidas mas que não podem ser associadas a uma operação determinada (mensagens desconhecidas).
ReplyAction– idem para mensagem de reply. Se for ‘*’ no servico indica que não
pretendemos gerar mensagens de reply. No cliente, um ‘*’ indica ao WCF para não validar a reply action.
IsOneWay– indica se esta operação não produz qualquer mensagem de resposta
(por omissão, false).
…
WCF
WCF
–
–
Contratos
Contratos
Operação One-Way
[ServiceContract]
public interface IServicoContas
{
[OperationContract]
float obterSaldo(int numero);
[OperationContract]
void alterarSaldo(int numero, float s);
[OperationContract(IsOneWay = true)]
void x();
// tem de ser void e sem parâmetros ref ou out
}
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 43
Operação One-Way
public class ServicoContas : IServicoContas
{
public float obterSaldo(int numero) {…}
public void alterarSaldo(int numero, float s) {…}
public void x()
{
Thread.Sleep(5000);
}
}
WCF
WCF
–
–
Contratos
Contratos
Operação One-Way
No cliente:
class Cliente
{
static void Main(string[] args) {
// para hospedeiro nosso:
ChannelFactory<IServicoContas>
servico = new ChannelFactory<IServicoContas>(…);
IServicoContas endpt = servico.CreateChannel();
…
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 45
Operação duplex
• Pode ser Request-Response ou One-Way
• É criado um novo canal para o sentido contrário (com o mesmo
protocolo) se o protocolo não o suportar (p. ex: http)
• O endereço no sentido contrário pode ser definido, mas, caso não o seja,
é determinado com base no endereço de rede de onde o serviço é
chamado.
WCF
WCF
–
–
Contratos
Contratos
Operação duplex: o serviço
namespace ServicoDuplex {
[ServiceContract(CallbackContract=typeof(IClienteCallback))] public interface IServico
{
[OperationContract] void LigaMe(); }
[ServiceContract]
public interface IClienteCallback {
[OperationContract] void EstouAligarTe(); }
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 47 public class Servico : IServico
{
public void LigaMe() { IClienteCallback c =
OperationContext.Current.GetCallbackChannel<IClienteCallback>(); ChamadaCliente chCli = new ChamadaCliente(c);
Thread t = new Thread(
new ThreadStart(chCli.Chamar)); t.IsBackground = true;
t.Start(); }
}
Operação duplex: o serviço
Permite acesso a informaçãosobre o contexto se execução de uma operação dum serviço
Informação sobre a thread corrente
WCF
WCF
–
–
Contratos
Contratos
public class ChamadaCliente
{
private IClienteCallback cli;
public ChamadaCliente(IClienteCallback c) {
cli = c;
}
public void Chamar() {
for(int i = 0; i < 10; ++i) {
cli.EstouAligarTe();
Thread.Sleep(5000);
}
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 49
public class Host
// Hospedeiro
{
public static void Main(string[] args)
{
ServiceHost host = new ServiceHost(typeof(Servico));
host.Open();
Console.WriteLine("Serviço iniciado. Enter para terminar");
Console.ReadLine();
host.Close();
}
}
}
Operação duplex: o serviço
WCF
WCF
–
–
Contratos
Contratos
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <services><service name="ServicoDuplex.Servico“ behaviorConfiguration="sb"> <host>
<baseAddresses>
<add baseAddress="http://localhost:8000/ServicoDuplex"/> </baseAddresses>
</host>
<endpoint address="" binding = "wsDualHttpBinding" contract="ServicoDuplex.IServico"/>
<endpoint address = "mex" binding = "mexHttpBinding" contract = "IMetadataExchange"/>
</service> </services>
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 51 <behaviors> <serviceBehaviors> <behavior name="sb"> <serviceMetadata httpGetEnabled="True"/> </behavior> </serviceBehaviors> </behaviors> </system.serviceModel> </configuration>
Operação duplex: o serviço
WCF
WCF
–
–
Contratos
Contratos
[ServiceContract(CallbackContract = typeof(IClienteCallback))] public interface IServico
{
[OperationContract] void LigaMe(); }
[ServiceContract]
public interface IClienteCallback {
[OperationContract] void EstouAligarTe(); }
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 53 namespace ClienteDuplexSemAddServRef
{
public class HandlerCallbackCliente : IClienteCallback {
public void EstouAligarTe() {
Console.WriteLine("Ligaram-me"); }
Operação duplex: o cliente (sem ajudas)
WCF
WCF
–
–
Contratos
Contratos
static void Main(string[] args) {
InstanceContext site = new InstanceContext(
new HandlerCallbackCliente());
// Assim para configuracao em código:
//WSDualHttpBinding binding = new WSDualHttpBinding(); //binding.ClientBaseAddress = // new Uri("http://localhost:8001/Cliente/"); //servico = //new DuplexChannelFactory<IServico>( // site, // binding, // new EndpointAddress("http://localhost:8000/ServicoDuplex") // );
Operação duplex: o cliente (sem ajudas)
Fornece contexto de execução de uma instância de um serviço Objecto que implementa a instância do serviçoArquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 55
// ou assim, para configuraçao em app.config:
DuplexChannelFactory<IServico> servico =
new DuplexChannelFactory<IServico>(site, "clienteServico"); IServico endpt = servico.CreateChannel();
endpt.LigaMe();
Console.WriteLine("Enter para terminar"); Console.ReadLine();
} } }
Operação duplex: o cliente (sem ajudas)
WCF
WCF
–
–
Contratos
Contratos
A configuração: <?xml version="1.0" encoding="utf-8" ?> <configuration> <system.serviceModel> <client> <endpoint name="clienteServico" address ="http://localhost:8000/ServicoDuplex" binding="wsDualHttpBinding" contract="IServico" bindingConfiguration=“MeuBindingDuplexCliente"/> </client>Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 57 A configuração:
<bindings>
<wsDualHttpBinding>
<binding name="MeuBindingDuplexCliente" clientBaseAddress="http://localhost:8001/Cliente/"> <security mode="Message"> <message clientCredentialType="Windows" negotiateServiceCredential="true" algorithmSuite="Default" /> </security> </binding> </wsDualHttpBinding> </bindings> </system.serviceModel> </configuration>
Operação duplex: o cliente (sem ajudas)
Se não for indicado, é usado um endereço baseado no endereço da máquina que invocou o serviço e com o memso porto
WCF
WCF
–
–
Contratos
Contratos
using ClienteDuplex.ServiceReference1; namespace ClienteDuplex {
public class HandlerCallbackCliente: IServicoCallback
{
public void EstouAligarTe() {
Console.WriteLine("Ligaram-me"); }
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 59 static void Main(string[] args)
{
InstanceContext site =
new InstanceContext(new HandlerCallbackCliente());
ServicoClient proxy = new ServicoClient(site); proxy.LigaMe();
Console.WriteLine("Enter para terminar"); Console.ReadLine();
} } }
Operação duplex: o cliente (com Add Service Reference)
WCF
WCF
–
–
Contratos
Contratos
... <system.serviceModel> <bindings> <wsDualHttpBinding> <binding name="WSDualHttpBinding_IServico" clientBaseAddress="http://localhost:8001/Cliente/"> ... </binding> </wsDualHttpBinding> </bindings> <client> <endpoint address="http://localhost:8000/ServicoDuplex" binding="wsDualHttpBinding" bindingConfiguration="WSDualHttpBinding_IServico" contract="ServiceReference1.IServico" name="WSDualHttpBinding_IServico">Se não se indicar, é usado um endereço baseado no do serviço, portanto, com o memso porto
Operação duplex: o cliente (com Add Service Reference)
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 61
Operação One-Way emparelhada versus Operação duplex
Paired one-way
Duplex
Os contratos podem ter versões
independentes. Os serviços
podem ser oferecidos a outros
clientes.
Os callback do lado do cliente
são determinados pelo serviço.
Novas versões do serviço podem
obrigar a alterações do cliente.
Forte compromisso com
situações onde o único
consumidor das operações do
cliente é o serviço.
Cada contrato one-way pode
definir os seus próprios bindings
e behavioirs
Os protocolos de comunicação
são os mesmos em ambas as
direcções porque dependem dos
bindings do serviço
WCF
WCF
–
–
Contratos
Contratos
Multiplos contratos no mesmo serviço:
namespace ServicoMultiplosContratos
{
[ServiceContract]
public interface IServico1 {
[OperationContract]
void op1();
}
[ServiceContract]
public interface IServico2 {
[OperationContract]
void op2();
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 63
Multiplos contratos no mesmo serviço:
public class Servico : IServico1,IServico2
{
public void op1()
{
Console.WriteLine("op1");
}
public void op2()
{
Console.WriteLine("op2");
}
}
WCF
WCF
–
–
Contratos
Contratos
Multiplos contratos no mesmo serviço:
public class Host // Hospedeiro
{
public static void Main(string[] args)
{
ServiceHost host =
new ServiceHost(typeof(Servico));
host.Open();
Console.WriteLine("Serviço iniciado. Enter para terminar");
Console.ReadLine();
host.Close();
}
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 65
Multiplos contratos no mesmo serviço:
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.serviceModel>
<services>
<service name="ServicoMultiplosContratos.Servico"
behaviorConfiguration="sb">
<host>
<baseAddresses>
<add baseAddress=
"http://localhost:8000/ExemploMultiplosContratos"/>
<add baseAddress=
"net.tcp://localhost:8002/ExemploMultiplosContratos"/>
</baseAddresses>
</host>
WCF
WCF
–
–
Contratos
Contratos
Multiplos contratos no memso serviço:
<endpoint address=""
name="
ep1
"
binding = "basicHttpBinding"
contract="
ServicoMultiplosContratos.IServico1
"/>
<endpoint address="adr2"
name ="
ep2
"
binding="netTcpBinding"
contract ="
ServicoMultiplosContratos.IServico1
"/>
<endpoint address="adr3"
name ="
ep3
" binding="basicHttpBinding"
contract ="
ServicoMultiplosContratos.IServico2
"/>
<endpoint address = "mex"
binding = "mexHttpBinding"
contract = "IMetadataExchange"/>
</service>
</services>
…
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 67
Multiplos contratos no mesmo serviço – o cliente:
using TesteServicoMultiplosContratos.
ServiceReference1
;
namespace TesteServicoMultiplosContratos
{
class Program
{
static void Main(string[] args) {
//Servico1Client proxy1 = new Servico1Client(); // assim dá erro!!!
Servico1Client proxy1 = new Servico1Client("ep1");
Servico1Client proxy2 = new Servico1Client("ep2");
Servico2Client proxy3 = new Servico2Client();
WCF
WCF
–
–
Contratos
Contratos
Multiplos contratos no mesmo serviço – o cliente:
Console.WriteLine("---");
proxy1.op1();
Console.WriteLine("=====");
proxy2.op1();
Console.WriteLine("*****");
proxy3.op2();
proxy1.Close();
proxy2.Close();
proxy3.Close();
}
}
}
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 69
Alteração de nomes WSDL:
Da forma como trabalhamos anteriormente, as descrições WSDL e, portanto, as mensagens trocadas com o serviço usam nomes derivados dos nomes das classes e interfaces utilizados.
O (XML) namespace associado ao <porttype> do serviço também é por omissão igual a “http://tempuri.org”.
Ora, este namespace apenas deve ser usado para desenvolvimento. Na exploração definitiva, cada organização deve usar os seus próprios target namespaces. Por outro lado, a exposição dos nossos nomes de codificação também pode não ser razoável, pois não permite ocultar aspectos internos da organização, como, por exemplo, standardas adoptados para a codificação de nomes.
Quando usamos serviços desenvolvidos por outros, a obrigação de usarmos os nomes conatantes da definição WSDL também não é razoável. Por exemplo, impede-nos de usar standards de codificação internos da organização.
O WCF permite-nos algum nível de controlo sobre estes aspectos
WCF
WCF
–
–
Contratos
Contratos
Alteração de nomes WSDL:
Termo WSDL Atributo WCF
targetNamespace Pode ser alterado com o atributo
[ServiceBehavior(Namespace=...)]
wsdl:service name [ServiceBehavior(Name=...)]
wsdl:portype namespace [ServiceContract(Namespace=...)]
wsdl:porttype name [ServiceContract(Name=...)]
wsdl:operation [OperationContract(Name=...)]
wsdl:input wsdl:output
[OperationContract(Action=..)] [OperationContract(ReplyAction=...)]
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 71
Data Contracts:
Como associar dados simples e complexos usados ao nível da programação
do serviço a dados representados por esquemas XML (XSD)
[DataContract]
public class Conta {
[DataMember]
public int Numero { get; set; }
[DataMember]
public string Titular { get; set; } public float Saldo { get; set; } }
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (representação XSD):
<?xml version="1.0" encoding="utf-8" ?> <xs:schema elementFormDefault="qualified"
targetNamespace="http://schemas.datacontract.org/2004/07/Servico1" xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:tns="http://schemas.datacontract.org/2004/07/Servico1">
<xs:complexType name="Conta"> <xs:sequence>
<xs:element minOccurs="0" name="Numero" type="xs:int" /> <xs:element minOccurs="0" name="Titular" nillable="true"
type="xs:string" /> </xs:sequence>
</xs:complexType>
<xs:element name="Conta" nillable="true" type="tns:Conta" />
</xs:schema> No caso concreto, aperecem por ordem alfabética
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 73 <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"> <s:Header> <To s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"> http://localhost:8000/Servico1 </To> <Action s:mustUnderstand="1" xmlns="http://schemas.microsoft.com/ws/2005/05/addressing/none"> http://tempuri.org/IServico/inserirConta </Action> </s:Header> <s:Body> <inserirConta xmlns="http://tempuri.org/"> <c xmlns:a="http://schemas.datacontract.org/2004/07/Servico1“ xmlns:i="http://www.w3.org/2001/XMLSchema-instance"> <a:Numero>7777</a:Numero> <a:Titular>Rita</a:Titular> </c> </inserirConta> </s:Body> </s:Envelope>
Mensagem soap resultante da serialização (por DataContractSerializer) para uma invocação da operação inserirConta(c). “c” é o nome do parâmetro no OperationContract
WCF
WCF
–
–
Contratos
Contratos
O serializador DataContractSerializer expõe em wsdl (na forma de XSD) e serializa para soap tipos que obedeçam a uma das seguintes condições:
1. Estejam marcados com [DataContract] e [DataMember] 2. Estejam marcados com [CollectionDataContract] 3. Derivem de IXmlSerializable
4. Estejam marcados com [Serializable] (sem membros marcados com
[NotSerializable]???)
5. Estejam marcados com [Serializable] e implementem ISerializable 6. Sejam tipos primitivos CLR (int32, string, …)
7. Sejam dos tipos arrays de bytes, DateTime, DateTimeOffset, TimeSpan, Guid, Uri, XmlQualifiedName, XmlElement e XmlNode
8. Sejam arrays e colecções dos tipos List<T>, Dictionary<K,V> e Hashtable 9. Sejam Enumerados
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 75
Data Contracts (colecções):
Não existe uma definição XSD ou WSDL standard equivalente às colecções
CLR (IEnumerable<T>). Assim, estes objectos são todos representados da
mesma forma. São, por isso, consumidos no cliente sempre como arrays.
No entanto, se no membro de um DataContract indicarmos outro tipo de
colecção (List, ArrayList, LinkedList,…), a desserialização fará essa
conversão se o indicarmos quando importamos o esquema XSD (através da
propriedade
ImportOptions
de
XsdDataContractImporter
). No visual
studio, isso é feito em “Add Service Reference” e “Configure Service
Reference”, pois podemos indicar como queremos que esses membros sejam
tratados.
Ver também o atributo [CollectionDataContract]
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (colecções): [ServiceContract]
public interface IServico {
[OperationContract]
Conta obterConta(int numero); [OperationContract]
List<Conta>
obterContas(List<int> numeros); …
}
[ServiceContract] public interface IServico {
[OperationContract]
Conta obterConta(int numero); [OperationContract]
Conta[]obterContas(int[] numeros); … } É importado através do serviço de mata-dados como:
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 77
Data Contracts (colecções):
…
<xs:complexType name="Conta">
…
</xs:complexType>
<xs:element name="Conta" nillable="true" type="tns:Conta" />
<xs:complexType name="ArrayOfConta">
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded"
name="Conta" nillable="true" type="tns:Conta" />
</xs:sequence>
</xs:complexType>
<xs:element name="ArrayOfConta" nillable="true“
type="tns:ArrayOfConta" />
…
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (colecções):
No cliente:
var contas = proxy.obterContas(new List<int> { 1, 3 });
dá origem à seguinte mensagem SOAP:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<To s:mustUnderstand="1“ xmlns=
"http://schemas.microsoft.com/ws/2005/05/addressing/none">
http://localhost:8000/Servico1
</To>
<Action s:mustUnderstand="1" xmlns=
"http://schemas.microsoft.com/ws/2005/05/addressing/none">
http://tempuri.org/IServico/obterContas
</Action>
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 79
Data Contracts (colecções):
<s:Body>
<
obterContas
xmlns="http://tempuri.org/">
<
numeros
xmlns:a=
"http://schemas.microsoft.com/2003/10/Serialization/Arrays"
xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<a:int>1</a:int>
<a:int>3</a:int>
</numeros>
</obterContas>
</s:Body>
</s:Envelope>
WCF
WCF
–
–
Contratos
Contratos
De notar que a descrição wsdl também inclui uma descrição XSD para definições dos parâmetros das operações (em http://localhost:8000/Servico1?xsd=xsd0):
<?xml version="1.0" encoding="utf-8" ?> <xs:schema elementFormDefault="qualified" ...>
...
<xs:element name="obterContas"> <xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="numeros" nillable="true" type="q2:ArrayOfint“ xmlns:q2=
"http://schemas.microsoft.com/2003/10/Serialization/Arrays" /> </xs:sequence>
</xs:complexType> </xs:element>
<xs:element name="obterContasResponse"> <xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="obterContasResult" nillable="true" type="q3:ArrayOfConta" xmlns:q3=
"http://schemas.datacontract.org/2004/07/Servico1" /> </xs:sequence>
<wsdl:message name="IServico_obterContas_InputMessage"> <wsdl:part name="parameters" element="tns:obterContas"/> </wsdl:message>
<wsdl:message name="IServico_obterContas_OutputMessage"> <wsdl:partname="parameters"
element="tns:obterContasResponse" /> </wsdl:message>
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 81
Também não esquecer:
… <wsdl:portType name="IServico"> … <wsdl:operation name="obterContas"> <wsdl:input wsaw:Action="http://tempuri.org/IServico/obterContas“ message="tns:IServico_obterContas_InputMessage" /> <wsdl:output wsaw:Action="http://tempuri.org/IServico/obterContasResponse" message="tns:IServico_obterContas_OutputMessage" /> </wsdl:operation> … </wsdl:portType>
<wsdl:message name="IServico_obterContas_InputMessage"> <wsdl:part name="parameters" element="tns:obterContas" /> </wsdl:message>
<wsdl:message name="IServico_obterContas_OutputMessage"> <wsdl:part name="parameters" element=
"tns:obterContasResponse" /> </wsdl:message>
WCF
WCF
–
–
Contratos
Contratos
Data contracts:
Propriedades de DataContract:Name– controla a propriedade name no elemento <xs:ComplexType> do XSD que define o tipo em termos de wsdl (por omissão, o nome qualificado da classe)
Namespace– idem, mas para a propriedade namespace (por omissão um nome
derivado do Namespace CLR (Clr.Namespace):
"http://schemas.datacontract.org/2004/07/Clr.Namespace")
...
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 83
Data contracts:
Propriedades de DataMember:
Name– controla a propriedade name no elemento <xs:element> do XSD que define o tipo em termos de wsdl (por omissão o nome do membro CLR)
EmitDefaultValue– controla se deve ser serializado o valor por omissão do
membro (por omissão, true).
IsRequired– Indica se o membro deve ou não estar presente no processo de
desserialização (ver controlo de versões). (por omissão, false).
Order– o número de ordem do membro na stream de serialização. Os membros
das classes base vêm primeiro, depois os da classe derivada não marcados com Order, por ordem alfabética e, por fim, os marcados com Order pela ordem definida e, dentro desta, por ordem alfabética (por omissão, order = -1).
...
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (known types):
[DataContract]
[KnownType(typeof(subClasse))]
public class Classe
{
…
}
[DataContract]
public class SubClasse : Classe
{
…
}
Pode ser indicado ao nível do [OperationContract] com o atributo
[ServiceKnownType], mas, neste caso, os tipos indicados podem apenas ser usados nas operações onde são indicados, ou em todas as operaçõees da interface se ServiceKnownType for usado ao nível da interface.
Se no destino apenas existir a classe Classe e chegar uma instância de SubClasse, a desserialização não consegue criar o objecto.
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 85
Data Contracts:
Em alternativa, podemos usar o nó <system.runtime.serialization> em
App.config ou Web.config para indicar known types:
<system.runtime.serialization>
<dataContractSerializer>
<declaredTypes>
<add type ="Classe, Minhadll, Version=1.0.0.0, Culture=neutral,
PublickeyToken=null">
<knownType type ="subClasse, MinhaDll, Version=1.0.0.0,
Culture=neutral, PublickeyToken=null"/>
</add>
</declaredTypes>
</dataContractSerializer>
</system.runtime.serialization>
WCF
WCF
–
–
Contratos
Contratos
Data Contracts:
Podemos ainda gerar os known types dinamicamente:
[DataContract]
[KnownTypes(“obterKnownTypes”)]
public class Classe
{
[DataMember]
public int x;
…
static Type[] obterKnownTypes() {
return new Type[] {typeof(subClasse),…};
}
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 87 Data Contracts (versões):
O data contracts podem sofrer algumas alterações sem quebra de compatibilidade, tais como adição ou remoção de membros não marcados com IsRequired = true. Uma consequência positiva é que serviço e clientes podem evoluir
independentemente uns dos outros (desde que se mantenha compatibilidade). Alterações com quebra de compatibilidade:
• Alteração das propriedades Name ou Namespace do data contract • Alteração do nome ou remoção de um membro que estava marcado com
IsRquired = true
• Adição de um novo membro com um nome usado anteriormente • Alteração do tipo de dados de um data member
• Adição de novos membros marcados com IsRequired = true
• Alteração da propriedade IsRequired de um DataMember de false para true
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (versões):
[DataContract] class Conta// versão 1
{
[DataMember]
public int Numero { get; set; } [DataMember]
public string Titular { get; set; } }
[DataContract] class Conta// versão 2
{
[DataMember(Name=“Numero”)] public int N { get; set; }
[DataMember]
public string Titular { get; set; } }
[DataContract] class Conta// versão 3
{
[DataMember(Name=“Numero”)]
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 89
Data Contracts (round- trip em versões):
[DataContract]public class Aluno// versão 1 {
[DataMember] public int Numero; [DataMember] public string Nome; }
[DataContract(Name=“Aluno”)] public class Aluno2 // versão 2 {
[DataMember] public int Numero; [DataMember] public string Nome; [DataMember(Order=3)] public string Telefone; }
Serviço usando Aluno versão 1 Cliente usando Aluno versão 2
call x(Aluno(v2) a)
retorna a (mas a versão 1)
O que acontece ao membro Telefone?
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (round- trip em versões):
[DataContract]public class Aluno : IExtensibleDataObject // versão 1 {
[DataMember] public int Numero; [DataMember] public string Nome;
private ExtensionDataObject dadosExtra; public virtual ExtensionDataObject ExtensionData {
get { return dadosExtra; } set {dadosExtra = value; } }
}
[DataContract(Name=“Aluno”)] public class Aluno2 // versão 2 {
[DataMember] public int Numero; [DataMember] public string Nome; [DataMember(Order=0)] public string Telefone; }
Boa prática, mas não necessário Lista com informação dos data members não
conhecidos (estes membros serão serializados se uma instância deste data contract for enviada)
Um serviço pode impedir este funcioamento através do atributo de comportamento
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 91
Data Contracts (versões):
Por omissão, muitas plataformas de serviços (incluindo o WCF) não
fazem validação do esquema dos data contracts, permitindo, por isso,
elementos extra não suportados pelo esquema. Nestes casos, os métodos
que vimos para lidar com versões são adequados.
Nos casos em que é necessário (ou as plataformas impõem) a validação de
esquemas, a regra é definir um novo data contract com outro nome ou
outro namespace (o recomendado) e proceder às alterações necessárias
para definição da nova funcionalidade associada à nova versão no service
contract.
WCF
WCF
–
–
Contratos
Contratos
Data Contracts (equivalência)
Dois data contracts são equivalentes se tiveram o mesmo namespace e o mesmo nome e se cada data member num deles tiver um data member equivalente no outro. A ordem dos membros também tem de ser a mesma.
Dois data members são equivalentes se tiverem o mesmo nome e o mesmo tipo de dados. Em suma, dois data contracts são equivalentes se gerarem a mesma descrição XSD.
DataContract] public class Contacto {
[DataMember] public string Nome; [DataMember] public string Telefone; }
[DataContract(Name = "Contacto")] public class Pessoa {
[DataMember(Name = “Nome")] private string NomeCompleto; private string address;
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 93
Data Contracts (equivalência)
DataContract] public class Contacto {
[DataMember(Order=1)] public string Nome; [DataMember(Order=0)] public string Telefone; }
[DataContract(Name = "Contacto")] public class Pessoa {
[DataMember(Name = “Nome")] private string NomeCompleto; private string address;
[DataMember(Name = “Telefone")] private string NumTel;
}
Data contracts não equivalentes
Ordem alfabética: Nome < Telefone
WCF
WCF
–
–
Contratos
Contratos
Message Contracts
Permitem trabalhar ao nível das mensagens SOAP.
Não veremos este tipo de contratos.
Arquitectura de Sistemas de Informação (ISEL-DEETC Walter Vieira) 95
Canais
São definidos para o transporte de mensagens, protocolos e intercepção de
mensagens. Funcionam agrupados em camadas.
Não aprofundaremos o tema canais nestas notas
Transporte
Protocolo
Protocolo
Aplicação
...
Os canais de protocolo permitem tratar aspectos de segurança, reliable messaging, transacções, etc.