Configurando e estendendo o tempo de execução com comportamentos
Os comportamentos permitem modificar o comportamento padrão e adicionar extensões personalizadas que inspecionam e validam a configuração do serviço ou modificam o comportamento do tempo de execução em aplicativos cliente e de serviço do Windows Communication Foundation (WCF). Este tópico descreve as interfaces de comportamento, como implementá-las e como adicioná-las à descrição do serviço (em um aplicativo de serviço) ou ponto de extremidade (em um aplicativo cliente) programaticamente ou em um arquivo de configuração. Para obter mais informações sobre como usar comportamentos fornecidos pelo sistema, consulte Especificando o comportamento de tempo de execução do serviço e Especificando o comportamento de tempo de execução do cliente.
Comportamentos
Os tipos de comportamento são adicionados aos objetos de descrição do ponto de extremidade do serviço ou do serviço (no serviço ou no cliente, respectivamente) antes que esses objetos sejam usados pelo Windows Communication Foundation (WCF) para criar um tempo de execução que executa um serviço WCF ou um cliente WCF. Quando esses comportamentos são chamados durante o processo de construção do tempo de execução, eles são capazes de acessar propriedades e métodos de tempo de execução que modificam o tempo de execução construído pelo contrato, associações e endereços.
Métodos de comportamento
Todos os comportamentos têm um AddBindingParameters
método, um ApplyDispatchBehavior
método, um Validate
método e um ApplyClientBehavior
método com uma exceção: Como IServiceBehavior não é possível executar em um cliente, ele não implementa ApplyClientBehavior
.
Use o
AddBindingParameters
método para modificar ou adicionar objetos personalizados a uma coleção que as associações personalizadas podem acessar para seu uso quando o tempo de execução é construído. Por exemplo, são especificados requisitos de proteção que afetam a maneira como o canal é criado, mas não são conhecidos pelo desenvolvedor do canal.Use o
Validate
método para examinar a árvore de descrição e o objeto de tempo de execução correspondente para garantir que ele esteja em conformidade com algum conjunto de critérios.Use os
ApplyDispatchBehavior
métodos eApplyClientBehavior
para examinar a árvore de descrição e modificar o tempo de execução para um escopo específico no serviço ou no cliente. Você também pode inserir objetos de extensão.Nota
Embora uma árvore de descrição seja fornecida nesses métodos, ela é apenas para exame. Se uma árvore de descrição for modificada, o comportamento será indefinido.
As propriedades que você pode modificar e as interfaces de personalização que você pode implementar são acessadas por meio das classes de tempo de execução do serviço e do cliente. Os tipos de serviço são as DispatchRuntime classes e DispatchOperation . Os tipos de cliente são as ClientRuntime classes e ClientOperation . As ClientRuntime classes e são os pontos de entrada de extensibilidade para acessar propriedades de tempo de execução e DispatchRuntime coleções de extensão em todo o cliente e em todo o serviço, respectivamente. Da mesma forma, as classes e expõem as propriedades de tempo de execução da operação do DispatchOperation cliente e da ClientOperation operação de serviço e as coleções de extensão, respectivamente. No entanto, você pode acessar o objeto de tempo de execução com escopo mais amplo a partir do objeto de tempo de execução da operação e vice-versa, se necessário.
Nota
Para obter uma discussão sobre propriedades de tempo de execução e tipos de extensão que você pode usar para modificar o comportamento de execução de um cliente, consulte Estendendo clientes. Para obter uma discussão sobre propriedades de tempo de execução e tipos de extensão que você pode usar para modificar o comportamento de execução de um dispatcher de serviço, consulte Estendendo dispatchers.
A maioria dos usuários do WCF não interage com o tempo de execução diretamente; Em vez disso, eles usam construções de modelo de programação principais, como pontos de extremidade, contratos, associações, endereços e atributos de comportamento em classes ou comportamentos em arquivos de configuração. Essas construções compõem a árvore de descrição, que é a especificação completa para construir um tempo de execução para dar suporte a um serviço ou cliente descrito pela árvore de descrição.
Existem quatro tipos de comportamentos no WCF:
Os comportamentos de serviço (IServiceBehavior types) permitem a personalização de todo o tempo de execução do serviço, incluindo ServiceHostBase.
Os comportamentos de ponto de extremidade (IEndpointBehavior types) permitem a personalização de pontos de extremidade de serviço e seus objetos associados EndpointDispatcher .
Os comportamentos de contrato (IContractBehavior tipos) permitem a personalização das ClientRuntime classes e DispatchRuntime em aplicativos cliente e de serviço, respectivamente.
Os comportamentos de operação (IOperationBehavior tipos) permitem a personalização das ClientOperation classes e DispatchOperation , novamente, no cliente e no serviço.
Você pode adicionar esses comportamentos aos vários objetos de descrição implementando atributos personalizados, usando arquivos de configuração do aplicativo ou adicionando-os diretamente à coleção de comportamentos no objeto de descrição apropriado. O deve, no entanto, ser adicionado a uma descrição de serviço ou objeto de descrição de ponto de extremidade de serviço antes de chamar ICommunicationObject.Open o ServiceHost ou um ChannelFactory<TChannel>.
Escopos de comportamento
Há quatro tipos de comportamento, cada um dos quais corresponde a um escopo específico de acesso em tempo de execução.
Comportamentos de serviço
Os comportamentos de serviço, que implementam IServiceBehavioro , são o mecanismo principal pelo qual você modifica todo o tempo de execução do serviço. Há três mecanismos para adicionar comportamentos de serviço a um serviço.
Usando um atributo na classe de serviço. Quando um ServiceHost é construído, a implementação usa reflexão ServiceHost para descobrir o conjunto de atributos no tipo de serviço. Se qualquer um desses atributos for implementações de , eles serão adicionados à coleção de IServiceBehaviorcomportamentos em ServiceDescription. Isso permite que esses comportamentos participem da construção do tempo de execução do serviço.
Adicionando programaticamente o comportamento à coleção de comportamentos no ServiceDescription. Isso pode ser feito com as seguintes linhas de código:
ServiceHost host = new ServiceHost(/* Parameters */); host.Description.Behaviors.Add(/* Service Behavior */);
Implementação de um personalizado BehaviorExtensionElement que estende a configuração. Isso permite o uso do comportamento de serviço a partir de arquivos de configuração do aplicativo.
Exemplos de comportamentos de serviço no WCF incluem o ServiceBehaviorAttribute atributo, o ServiceThrottlingBehaviore o ServiceMetadataBehavior comportamento.
Comportamentos contratuais
Os comportamentos contratuais, que implementam a IContractBehavior interface, são usados para estender o tempo de execução do cliente e do serviço em um contrato.
Existem dois mecanismos para adicionar comportamentos contratuais a um contrato. O primeiro mecanismo é criar um atributo personalizado para ser usado na interface do contrato. Quando uma interface de contrato é passada para um ServiceHost ou um ChannelFactory<TChannel>, o WCF examina os atributos na interface. Se quaisquer atributos forem implementações de , eles serão adicionados à coleção de IContractBehaviorcomportamentos na System.ServiceModel.Description.ContractDescription interface criada para essa interface.
Você também pode implementar o System.ServiceModel.Description.IContractBehaviorAttribute atributo de comportamento de contrato personalizado. Neste caso, o comportamento é o seguinte quando aplicado a:
•Uma interface de contrato. Nesse caso, o comportamento é aplicado a todos os contratos desse tipo em qualquer ponto de extremidade e o WCF ignora o IContractBehaviorAttribute.TargetContract valor da propriedade.
•Uma classe de serviço. Neste caso, o comportamento é aplicado apenas aos pontos finais cujo contrato é o valor do TargetContract imóvel.
•Uma classe de retorno de chamada. Nesse caso, o comportamento é aplicado ao ponto de extremidade do cliente duplex e o WCF ignora o TargetContract valor da propriedade.
O segundo mecanismo é adicionar o comportamento à coleção de comportamentos em um ContractDescriptionarquivo .
Exemplos de comportamentos contratuais no WCF incluem o System.ServiceModel.DeliveryRequirementsAttribute atributo. Para obter mais informações e um exemplo, consulte o tópico de referência.
Comportamentos de ponto final
Os comportamentos de ponto de extremidade, que implementam IEndpointBehavior, são o mecanismo principal pelo qual você modifica todo o tempo de execução do serviço ou cliente para um ponto de extremidade específico.
Há dois mecanismos para adicionar comportamentos de ponto de extremidade a um serviço.
Adicione o comportamento à Behaviors propriedade.
Implemente um personalizado BehaviorExtensionElement que estenda a configuração.
Para obter mais informações e um exemplo, consulte o tópico de referência.
Comportamentos de Operação
Os comportamentos de operação, que implementam a IOperationBehavior interface, são usados para estender o tempo de execução do cliente e do serviço para cada operação.
Existem dois mecanismos para adicionar comportamentos de operação a uma operação. O primeiro mecanismo é criar um atributo personalizado para ser usado no método que modela a operação. Quando uma operação é adicionada a um ServiceHost ou a , ChannelFactoryo WCF adiciona quaisquer IOperationBehavior atributos à coleção de comportamentos no OperationDescription criado para essa operação.
O segundo mecanismo é adicionando diretamente o comportamento à coleção de comportamentos em um construído OperationDescription.
Exemplos de comportamentos de operação no WCF incluem o OperationBehaviorAttribute e o TransactionFlowAttribute.
Para obter mais informações e um exemplo, consulte o tópico de referência.
Usando a configuração para criar comportamentos
Os comportamentos de serviço, ponto de extremidade e contrato podem ser projetados para serem especificados em código ou usando atributos; somente comportamentos de serviço e ponto de extremidade podem ser configurados usando arquivos de configuração do aplicativo ou da Web. Expor comportamentos usando atributos permite que os desenvolvedores especifiquem um comportamento em tempo de compilação que não pode ser adicionado, removido ou modificado em tempo de execução. Isso geralmente é adequado para comportamentos que são sempre necessários para a operação correta de um serviço (por exemplo, os parâmetros relacionados à transação para o System.ServiceModel.ServiceBehaviorAttribute atributo). Expor comportamentos usando a configuração permite que os desenvolvedores deixem a especificação e a configuração desses comportamentos para aqueles que implantam o serviço. Isso é adequado para comportamentos que são componentes opcionais ou outra configuração específica da implantação, como se os metadados são expostos para o serviço ou a configuração de autorização específica para um serviço.
Nota
Você também pode usar comportamentos que oferecem suporte à configuração para impor políticas de aplicativos da empresa, inserindo-os no arquivo de configuração machine.config e bloqueando esses itens. Para obter uma descrição e um exemplo, consulte Como bloquear pontos de extremidade na empresa.
Para expor um comportamento usando a configuração, um desenvolvedor deve criar uma classe derivada de BehaviorExtensionElement e, em seguida, registrar essa extensão com a configuração.
O exemplo de código a seguir mostra como um IEndpointBehavior implementa BehaviorExtensionElement:
// BehaviorExtensionElement members
public override Type BehaviorType
{
get { return typeof(EndpointBehaviorMessageInspector); }
}
protected override object CreateBehavior()
{
return new EndpointBehaviorMessageInspector();
}
Para que o sistema de configuração carregue um personalizado BehaviorExtensionElement, ele deve ser registrado como uma extensão. O exemplo de código a seguir mostra o arquivo de configuração para o comportamento de ponto de extremidade anterior:
<configuration>
<system.serviceModel>
<services>
<service
name="Microsoft.WCF.Documentation.SampleService"
behaviorConfiguration="metadataSupport"
>
<host>
<baseAddresses>
<add baseAddress="http://localhost:8080/ServiceMetadata" />
</baseAddresses>
</host>
<endpoint
address="/SampleService"
binding="wsHttpBinding"
behaviorConfiguration="withMessageInspector"
contract="Microsoft.WCF.Documentation.ISampleService"
/>
<endpoint
address="mex"
binding="mexHttpBinding"
contract="IMetadataExchange"
/>
</service>
</services>
<behaviors>
<serviceBehaviors>
<behavior name="metadataSupport">
<serviceMetadata httpGetEnabled="true" httpGetUrl=""/>
</behavior>
</serviceBehaviors>
<endpointBehaviors>
<behavior name="withMessageInspector">
<endpointMessageInspector />
</behavior>
</endpointBehaviors>
</behaviors>
<extensions>
<behaviorExtensions>
<add
name="endpointMessageInspector"
type="Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector, HostApplication, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null"
/>
</behaviorExtensions>
</extensions>
</system.serviceModel>
</configuration>
Onde Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector
é o tipo de extensão de comportamento e HostApplication
é o nome do assembly no qual essa classe foi compilada.
Ordem de Avaliação
O System.ServiceModel.ChannelFactory<TChannel> e o System.ServiceModel.ServiceHost são responsáveis por construir o tempo de execução a partir do modelo de programação e descrição. Os comportamentos, conforme descrito anteriormente, contribuem para esse processo de construção no serviço, no ponto final, no contrato e na operação.
Os ServiceHost comportamentos se aplicam na seguinte ordem:
Serviço
Contract
Ponto final
Operação
Dentro de qualquer coleção de comportamentos, nenhuma ordem é garantida.
Os ChannelFactory<TChannel> comportamentos se aplicam na seguinte ordem:
Contract
Ponto final
Operação
Dentro de qualquer coleção de comportamentos, novamente, nenhuma ordem é garantida.
Adicionando comportamentos programaticamente
As propriedades do no aplicativo de System.ServiceModel.Description.ServiceDescription serviço não devem ser modificadas posteriormente ao CommunicationObject.OnOpening método em System.ServiceModel.ServiceHostBase. Alguns membros, como a ServiceHostBase.Credentials propriedade e os AddServiceEndpoint
métodos em ServiceHostBase e System.ServiceModel.ServiceHost, lançam uma exceção se modificados após esse ponto. Outros permitem modificá-los, mas o resultado é indefinido.
Da mesma forma, no cliente os System.ServiceModel.Description.ServiceEndpoint valores não devem ser modificados após a chamada para OnOpening no System.ServiceModel.ChannelFactory. A ChannelFactory.Credentials propriedade lança uma exceção se modificada após esse ponto, mas os outros valores de descrição do cliente podem ser modificados sem erro. O resultado, no entanto, é indefinido.
Seja para o serviço ou cliente, é recomendável que você modifique a descrição antes de chamar CommunicationObject.Open.
Regras de herança para atributos de comportamento
Todos os quatro tipos de comportamentos podem ser preenchidos usando atributos – comportamentos de serviço e comportamentos contratuais. Como os atributos são definidos em objetos e membros gerenciados, e os objetos e membros gerenciados suportam herança, é necessário definir como os atributos de comportamento funcionam no contexto da herança.
Em um nível alto, a regra é que, para um escopo específico (por exemplo, serviço, contrato ou operação), todos os atributos de comportamento na hierarquia de herança para esse escopo são aplicados. Se houver dois atributos de comportamento do mesmo tipo, somente o tipo mais derivado será usado.
Comportamentos de serviço
Para uma determinada classe de serviço, todos os atributos de comportamento de serviço nessa classe e nos pais dessa classe são aplicados. Se o mesmo tipo de atributo for aplicado em vários locais na hierarquia de herança, o tipo mais derivado será usado.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirementsAttribute(
AspNetCompatibilityRequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class A { /* … */ }
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class B : A { /* … */}
Por exemplo, no caso anterior, o serviço B termina com um InstanceContextMode de , um AspNetCompatibilityRequirementsMode modo de Allowed, e um ConcurrencyMode de SingleSingle. O ConcurrencyMode é Single, porque ServiceBehaviorAttribute o atributo no serviço B está em "mais derivado" do que o atributo no serviço A.
Comportamentos contratuais
Para um determinado contrato, todos os atributos de comportamento do contrato nessa interface e nos pais dessa interface são aplicados. Se o mesmo tipo de atributo for aplicado em vários locais na hierarquia de herança, o tipo mais derivado será usado.
Comportamentos de Operação
Se uma determinada operação não substituir uma operação abstrata ou virtual existente, nenhuma regra de herança se aplica.
Se uma operação substituir uma operação existente, todos os atributos de comportamento da operação nessa operação e nos pais dessa operação serão aplicados. Se o mesmo tipo de atributo for aplicado em vários locais na hierarquia de herança, o tipo mais derivado será usado.