Configuración y extensión del tiempo de ejecución con comportamientos
Los comportamientos le permiten modificar el comportamiento predeterminado y agregar extensiones personalizadas que inspeccionan y validan la configuración de servicio o modifican el comportamiento del tiempo de ejecución en el cliente Windows Communication Foundation (WCF) y las aplicaciones de servicio. En este tema se describen las interfaces de comportamiento, cómo implementarlas y cómo agregarlas mediante programación a la descripción del servicio (en una aplicación de servicio) o extremo (en una aplicación cliente) o en un archivo de configuración. Para obtener más información sobre cómo utilizar los comportamientos proporcionados por el sistema, vea Especificación del comportamiento en tiempo de ejecución del servicio y Especificación del comportamiento de tiempo de ejecución del cliente.
Comportamientos
Los tipos de comportamiento se agregan al servicio o a los objetos de descripción de extremos de servicio (en el servicio o cliente, respectivamente) antes de que estos objetos los utilice Windows Communication Foundation (WCF) para crear un tiempo de ejecución que ejecute un servicio WCF o un cliente WCF. Cuando se llama a estos comportamientos durante el proceso de construcción en tiempo de ejecución, podrá tener acceso a las propiedades y métodos en tiempo de ejecución que modifican el tiempo de ejecución construido por el contrato, enlaces y direcciones.
Métodos de comportamiento
Todo los comportamientos tienen un método AddBindingParameters, un método ApplyDispatchBehavior, un método Validate y un método ApplyClientBehavior con una excepción: como IServiceBehavior no puede ejecutarse en un cliente, no implementará ApplyClientBehavior.
Utilice el método AddBindingParameters para modificar o agregar los objetos personalizados a una colección a la que los enlaces personalizados pueden tener acceso para su uso cuando se construya el tiempo de ejecución. Por ejemplo, la forma en que se especifican los requisitos de protección que afectan a la manera en que se crea el canal pero no es conocido por el desarrollador de canales.
Utilice el método Validate para examinar el árbol de descripción y el objeto del tiempo de ejecución correspondiente para garantizar que se ajusta a algún conjunto de criterios.
Utilice los métodos ApplyDispatchBehavior y ApplyClientBehavior para examinar el árbol de descripción y modificar el tiempo de ejecución para un ámbito determinado en el servicio o el cliente. También puede insertar los objetos de extensión.
Nota
Aunque se proporciona un árbol de descripción en estos métodos, sólo es para el examen. Si se modifica un árbol de descripción, el comportamiento es indefinido.
Se tiene acceso a las propiedades que puede modificar y las interfaces de personalización que puede implementar a través de las clases de tiempo de ejecución de servicio y de cliente. Los tipos de servicio son las clases DispatchRuntime y DispatchOperation. Los tipos de cliente con las clases ClientRuntime y ClientOperation. Las clases ClientRuntime y DispatchRuntime son los puntos de entrada de la extensibilidad para tener acceso a las propiedades en tiempo de ejecución del cliente y del servicio y las colecciones de extensión, respectivamente. De igual forma, las clases ClientOperation y DispatchOperation exponen las propiedades del tiempo de ejecución de la operación del cliente y de la operación de servicio, y las colecciones de extensiones, respectivamente. Puede, sin embargo, tener acceso al objeto en tiempo de ejecución de un ámbito más amplio a partir del objeto de tiempo de ejecución de la operación y viceversa, si fuera necesario.
Nota
Para obtener una explicación de las propiedades en tiempo de ejecución y los tipos de extensión que puede utilizar para modificar el comportamiento de ejecución de un cliente, vea Extensión de clientes. Para obtener una explicación de las propiedades en tiempo de ejecución y los tipos de extensión que puede utilizar para modificar el comportamiento de ejecución de un distribuidor de servicio, vea Extensión de distribuidores.
La mayoría de los usuarios WCF no interactúan directamente con el tiempo de ejecución; en su lugar utilizan las construcciones del modelo de programación básicas como los extremos, contratos, enlaces, direcciones y atributos de comportamiento en clases o comportamientos en archivos de configuración. Estas estructuras constituyen el árbol de descripción, que es la especificación completa para construir un tiempo de ejecución para admitir un servicio o el cliente descrito por el árbol de descripción.
Hay cuatro tipos de comportamientos en WCF:
- Los comportamientos de servicio (tipos IServiceBehavior) permiten la personalización del tiempo de ejecución del servicio completo incluido ServiceHostBase.
- Los comportamientos del extremo (tipos IEndpointBehavior) permiten la personalización de los extremos de servicio y sus objetos EndpointDispatcher asociados.
- Los comportamientos del contrato (tipos IContractBehavior) permiten la personalización de las clases ClientRuntime y DispatchRuntime en las aplicaciones de cliente y servicio, respectivamente.
- Los comportamientos de la operación (tipos IOperationBehavior) permiten la personalización de las clases ClientOperation y DispatchOperation, de nuevo, en el cliente y el servicio.
Puede agregar estos comportamientos a los distintos objetos de descripción implementando los atributos personalizados, utilizando los archivos de configuración de la aplicación, o directamente agregándolos a la colección de comportamientos en el objeto de descripción adecuado. Sin embargo, deben agregarse a la descripción del servicio o a un objeto de descripción del extremo del servicio antes de llamar a System.ServiceModel.ICommunicationObject.Open en ServiceHost o ChannelFactory.
Ámbitos de comportamiento
Hay cuatro tipos de comportamiento, cada uno de los cuales se corresponde con un ámbito determinado de acceso en tiempo de ejecución.
Comportamientos de servicio
Los comportamientos de servicio, que implementan IServiceBehavior, son el mecanismo principal por medio del cual modifica el tiempo de ejecución del servicio completo. Hay tres mecanismos para agregar los comportamientos de servicio a un servicio.
Utilizar un atributo en la clase de servicio. Cuando se construye un ServiceHost, la implementación de ServiceHost utiliza la reflexión para detectar el conjunto de atributos en el tipo del servicio. Si cualquiera de estos atributos es una implementación de IServiceBehavior, se agregan a la colección de comportamientos en ServiceDescription. Esto permite a esos comportamientos participar en la construcción del tiempo de ejecución del servicio.
Agregar mediante programación el comportamiento a la colección de comportamientos en ServiceDescription. Esto se puede lograr con las siguientes líneas de código:
ServiceHost host = new ServiceHost(/* Parameters */); host.Description.Behaviors.Add(/* Service Behavior */);
Implementar un BehaviorExtensionElement personalizado que extiende la configuración. Esto permite el uso del comportamiento de servicio a partir de los archivos de configuración de la aplicación.
Los ejemplos de comportamientos de servicio en WCF incluyen el atributo ServiceBehaviorAttribute, ServiceThrottlingBehavior y el comportamiento ServiceMetadataBehavior.
Comportamientos de contrato
Los comportamientos de contrato, que implementan la interfaz IContractBehavior, se utilizan para extender el tiempo de ejecución del cliente y el servicio en un contrato.
Hay dos mecanismos para agregar los comportamientos del contrato a un contrato. El primer mecanismo es crear un atributo personalizado que se va a utilizar en la interfaz de contrato. Cuando una interfaz de contrato se pasa a ServiceHost o a ChannelFactory, WCF examina los atributos en la interfaz. Si los atributos son implementaciones de IContractBehavior, se agregarán a la colección de comportamientos en el System.ServiceModel.Description.ContractDescription creado para esa interfaz.
También puede implementar System.ServiceModel.Description.IContractBehaviorAttribute en el atributo de comportamiento de contrato personalizado. En este caso, el comportamiento es como sigue cuando se aplica a:
•Una interfaz de contrato. En este caso, el comportamiento se aplica a todos los contratos de ese tipo en cualquier extremo y WCF omite el valor de la propiedad System.ServiceModel.Description.IContractBehaviorAttribute.TargetContract.
•Una clase de servicio. En este caso, el comportamiento se aplica sólo a los extremos cuyo contrato es el valor de la propiedad TargetContract.
•Una clase de devolución de llamada. En este caso, el comportamiento se aplica al extremo del cliente dúplex e WCF omite el valor de la propiedad TargetContract.
El segundo mecanismo es agregar el comportamiento a la colección de comportamientos en ContractDescription.
Los ejemplos de comportamientos de contrato en WCF incluyen el atributo System.ServiceModel.DeliveryRequirementsAttribute. Para obtener más información y un ejemplo, vea el tema de referencia.
Comportamientos del extremo
Los comportamientos del extremo, que implementan IEndpointBehavior, son el mecanismo principal por medio del cual modifica todo el servicio o el tiempo de ejecución del cliente para un extremo concreto.
Hay dos mecanismos para agregar los comportamientos del extremo a un servicio.
- Agregue el comportamiento a la propiedad Behaviors.
- Implementar un BehaviorExtensionElement personalizado que extiende la configuración.
Para obtener más información y un ejemplo, vea el tema de referencia.
Comportamientos de la operación
Los comportamientos de la operación, que implementan la interfaz IOperationBehavior, se utilizan para extender el tiempo de ejecución del cliente y el servicio para cada operación.
Hay dos mecanismos para agregar los comportamientos de la operación a una operación. El primero es crear un atributo personalizado que se va a utilizar en el método que modela la operación. Cuando una operación se agrega a ServiceHost o a ChannelFactory, WCF agrega cualquier atributo IOperationBehavior a la colección de comportamientos en el OperationDescription creado para esa operación.
El segundo mecanismo es agregar directamente el comportamiento a la colección de comportamientos en un OperationDescriptionconstruido.
Los ejemplos de comportamientos de la operación en WCF incluyen OperationBehaviorAttribute y TransactionFlowAttribute.
Para obtener más información y un ejemplo, vea el tema de referencia.
Uso de la configuración para crear comportamientos
Los comportamientos de servicio y extremo, y contrato pueden diseñarse para que se especifiquen en el código o utilicen atributos; sólo se pueden configurar los comportamientos de servicio y extremo mediante la aplicación o los archivos de configuración web. La exposición de comportamientos con atributos permite a los desarrolladores especificar un comportamiento en el momento de la compilación que no puede agregarse, eliminarse ni modificarse en el tiempo de ejecución. Esto es a menudo conveniente para los comportamientos que siempre se necesitan para la operación correcta de un servicio (por ejemplo, los parámetros relacionados con la transacción al atributo System.ServiceModel.ServiceBehaviorAttribute). Exponer comportamientos que utilizan la configuración permite a los desarrolladores dejar la especificación y la configuración de dichos comportamientos a los que implementan el servicio. Esto es conveniente para los comportamientos que son componentes opcionales u otra configuración específica de la implementación, por ejemplo, si los metadatos se exponen para el servicio o la configuración de autorización determinada para un servicio.
Nota
También puede utilizar comportamientos que admiten la configuración para exigir las directivas de aplicación de la empresa insertándolas en el archivo de configuración machine.config y bloqueando esos elementos. Para obtener una descripción y un ejemplo, vea Cómo bloquear extremos en la empresa.
Para exponer un comportamiento mediante la configuración, un desarrollador debe crear una clase derivada de BehaviorExtensionElement y, a continuación, registrar esa extensión con la configuración.
El siguiente ejemplo de código muestra cómo IEndpointBehavior implementa BehaviorExtensionElement:
Para que el sistema de configuración cargue un BehaviorExtensionElement personalizado, se debe registrar como una extensión. El ejemplo de código siguiente muestra el archivo de configuración para el comportamiento del extremo anterior:
Donde Microsoft.WCF.Documentation.EndpointBehaviorMessageInspector
es el tipo de extensión de comportamiento y HostApplication
es el nombre del ensamblado en el que se ha compilado esa clase.
Orden de evaluación
System.ServiceModel.ChannelFactory y System.ServiceModel.ServiceHost son responsables de generar el tiempo de ejecución del modelo de programación y descripción. Los comportamientos, tal y como se han descritos previamente, contribuyen a ese proceso de creación en el servicio, extremo, contrato y operación.
ServiceHost aplica los comportamientos en el orden siguiente:
- Contrato
- Operación
- Extremo
- Servicio
Dentro de cualquier colección de comportamientos, no se garantiza ningún orden.
ChannelFactory aplica los comportamientos en el orden siguiente:
- Contrato
- Endpoint
- Operación
De nuevo, dentro de cualquier colección de comportamientos, no se garantiza ningún orden.
Adición de comportamientos mediante programación
Las propiedades de System.ServiceModel.Description.ServiceDescription en la aplicación de servicio no se deben modificar después del método System.ServiceModel.Channels.CommunicationObject.OnOpening en System.ServiceModel.ServiceHostBase. Algunos miembros, como la propiedad System.ServiceModel.ServiceHostBase.Credentials y los métodos AddServiceEndpoint en ServiceHostBase y System.ServiceModel.ServiceHost, producen una excepción si se modificas pasados ese punto. Otros le permiten modificarlos, pero el resultado es indefinido.
De igual forma, en el cliente los valores System.ServiceModel.Description.ServiceEndpoint no se deben modificar después de la llamada a OnOpening en System.ServiceModel.ChannelFactory. La propiedad System.ServiceModel.ChannelFactory.Credentials produce una excepción si se modifica pasado ese punto, pero los otros valores de descripción del cliente se pueden modificar sin el error. El resultado, sin embargo, es indefinido.
Tanto si es para el servicio o el cliente, se recomienda que modifique la descripción antes de llamar a System.ServiceModel.Channels.CommunicationObject.Open.
La herencia gobierna para los atributos de comportamiento
Los cuatro tipos de comportamientos se pueden rellenar utilizando los atributos: los comportamientos de servicio y de contrato. Debido a que los atributos se definen en los objetos y miembros administrados y éstos admiten la herencia, será necesario definir cómo funcionan los atributos en el contexto de la herencia.
En un nivel alto, la regla es que para un ámbito determinado (por ejemplo, servicio, contrato u operación) se aplican todos los atributos de comportamiento en la jerarquía de la herencia para ese ámbito. Si hay dos atributos de comportamiento del mismo tipo, sólo se utiliza el tipo más derivado.
Comportamientos de servicio
Para una clase de servicio determinada, se aplicarán todos los atributos de comportamiento del servicio en esa clase y en los elementos primarios de esa clase. Si el mismo tipo de atributo se aplica en varios lugares en la jerarquía de la herencia, se usará el tipo más derivado.
[ServiceBehavior(ConcurrencyMode = ConcurrencyMode.Multiple)]
[AspNetCompatibilityRequirementsAttribute(
AspNetCompatibilityRequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
public class A { /* … */ }
[ServiceBehavior(InstanceContextMode = InstanceContextMode.Single)]
public class B : A { /* … */}
Por ejemplo, en el caso anterior, el servicio B finaliza con un InstanceContextMode de Single, un modo AspNetCompatibilityRequirementsMode de Allowed y un ConcurrencyMode de Single. ConcurrencyMode es Single, porque el atributo ServiceBehaviorAttribute en el servicio B está "más derivado" que en el servicio A.
Comportamientos de contrato
Para un contrato determinado, se aplicarán todos los atributos de comportamiento de contrato en esa interfaz y en los elementos primarios de esa interfaz. Si el mismo tipo de atributo se aplica en varios lugares en la jerarquía de la herencia, se usará el tipo más derivado.
Comportamientos de la operación
Si una operación determinada no invalida ningún resumen existente ni la operación virtual, no se aplicará ninguna regla de herencia.
Si una operación invalida una operación existente, se aplicarán todos los atributos de comportamiento de operación en esa operación y en los elementos primarios de esa operación. Si el mismo tipo de atributo se aplica en varios lugares en la jerarquía de la herencia, se usará el tipo más derivado.