Extensión de distribuidores
El nivel de modelo de servicio es responsable de extraer los mensajes entrantes de los canales subyacentes, de modo que los traduce en código de aplicación en las invocaciones de método y devuelve los resultados al agente de llamada. Las extensiones de modelo de servicio modifican o implementan el comportamiento de la comunicación o la ejecución y características implicadas en la funcionalidad de distribuidor o cliente, comportamientos personalizados, interceptación de mensajes y parámetros, y otra funcionalidad de extensibilidad.
En este tema se describe cómo utilizar las clases DispatchRuntime y DispatchOperation en una aplicación de servicio de Windows Communication Foundation (WCF) para modificar el comportamiento de ejecución predeterminado de un distribuidor o para interceptar o modificar mensajes, parámetros o valores devueltos antes o después de enviar o recuperarlos desde el nivel del canal. Para obtener más información acerca del procesamiento de mensajes en tiempo de ejecución de cliente equivalente, vea Extensión de clientes. Para entender la función que desempeñan los IExtensibleObject tipos para tener acceso al estado compartido entre varios objetos de personalización en tiempo de ejecución, vea Objetos extensibles.
Distribuidores
El nivel del modelo de servicios realiza la conversión entre el modelo de programación del programador y el intercambio de mensajes subyacentes, comúnmente denominado el nivel de canal. En WCF los distribuidores de canales y extremos (ChannelDispatcher y EndpointDispatcher, respectivamente) son los componentes de servicio responsables de aceptar nuevos canales, recibir mensajes, distribuir e invocar operaciones y procesar las respuestas. Los objetos de distribuidor son objetos de receptor, pero las implementaciones de contratos de devolución de llamadas en servicios dúplex también exponen sus objetos de distribuidor para la inspección, modificación o extensión.
El distribuidor de canales (y IChannelListener complementario) extrae los mensajes del canal del subordinado y pasa los mensajes a sus distribuidores de extremos respectivos. Cada distribuidor de extremos tiene un DispatchRuntime que enruta los mensajes a la DispatchOperation adecuada, que es responsable de llamar al método que implementa la operación. Varias clases de extensiones opcionales y obligatorias se invocan e implican durante el proceso. En este tema se explica cómo encajan estas piezas, y cómo podría modificar las propiedades e introducir su propio código para extender la funcionalidad básica.
Las propiedades del distribuidor y los objetos de personalización modificados se insertan utilizando objetos de comportamiento de operación, servicio, extremo, o contrato. En este tema no se describe cómo utilizar los comportamientos. Para obtener más información sobre los tipos utilizados para insertar modificaciones de distribuidor, vea Cómo bloquear extremos en la empresa.
El siguiente gráfico proporciona una vista de alto nivel de los elementos arquitectónicos de un servicio.
Distribuidores de canal
Un objeto ChannelDispatcher se crea para asociar un IChannelListener de un URI determinado (denominado URI de escucha) a una instancia de un servicio. Cada objeto ServiceHost puede, por tanto, tener muchos objetos ChannelDispatcher, cada uno asociado a un sólo agente de escucha y URI de escucha. Cuando llega un mensaje, el objeto ChannelDispatcher consulta a cada uno de los objetos EndpointDispatcher asociados para saber si el extremo puede aceptar el mensaje, y pasa el mensaje a uno que pueda.
Todas las propiedades que controlan la duración y el comportamiento de una sesión de canal se pueden inspeccionar o modificar en el objeto ChannelDispatcher. Entre ellos se incluyen los inicializadores de canales personalizados, el agente de escuchas de canal, el host, el InstanceContextasociado, etc.
Distribuidores de extremos
El objeto EndpointDispatcher es responsable de procesar los mensajes de un objeto ChannelDispatcher cuando la dirección de destino de un mensaje coincide con la propiedad AddressFilter y la acción del mensaje coincide con la propiedad ContractFilter. Si dos objetos EndpointDispatcher pueden aceptar un mensaje, el valor de la propiedad FilterPriority determina el extremo de mayor prioridad.
Utilice el EndpointDispatcher para adquirir los dos puntos de extensión de modelo de servicio principales, las clases DispatchRuntime y DispatchOperation, que puede utilizar para personalizar el procesamiento del distribuidor. La clase DispatchRuntime permite a los usuarios interceptar y extender el distribuidor en el ámbito del contrato (es decir, para todos los mensajes de un contrato). La clase DispatchOperation permite a los usuarios interceptar y extender el distribuidor en un ámbito de operación (es decir, para todos los mensajes de una operación).
Escenarios
Hay varias razones para extender el distribuidor:
Validación personalizada del mensaje. Los usuarios pueden exigir que un mensaje sea válido para un determinado esquema. Esto se puede hacer implementando las interfaces del interceptor de mensajes. Vea un ejemplo en Message Inspectors.
Registro personalizado de mensajes. Los usuarios pueden inspeccionar y registrar un conjunto de mensajes de la aplicación que fluyen a través de un extremo. Esto también se puede lograr con las interfaces del interceptor de mensajes.
Transformaciones personalizadas del mensaje. Los usuarios pueden aplicar ciertas transformaciones al mensaje en el tiempo de ejecución (por ejemplo, para el control de versiones). Esto también se puede lograr, de nuevo, con las interfaces del interceptor de mensajes.
Modelo de datos personalizado. Los usuarios pueden tener un modelo de serialización de datos distinto de aquellos admitidos de forma predeterminada en WCF (a saber, System.Runtime.Serialization.DataContractSerializer, System.Xml.Serialization.XmlSerializer y los mensajes sin formato). Esto se puede hacer implementando las interfaces del formateador de mensajes. Vea un ejemplo en Operation Formatter And Operation Selector.
Validación personalizada de parámetros. Los usuarios pueden exigir que los parámetros con tipo sean válidos (por oposición a XML). Esto puede hacerse mediante las interfaces del inspector de parámetros. Vea un ejemplo en Parameter Filter.
Distribución de operaciones personalizadas. Los usuarios pueden implementar la distribución en algo que no sea una acción; por ejemplo, en el elemento de cuerpo o en una propiedad de un mensaje personalizado. Esto se puede hacer mediante la interfaz IDispatchOperationSelector. Vea un ejemplo en Operation Formatter And Operation Selector.
Agrupación de objetos. Los usuarios pueden agrupar instancias en lugar de asignar una nueva instancia a cada llamada. Esto se puede implementar mediante las interfaces proveedoras de instancias. Vea un ejemplo en Pooling.
Arrendamiento de instancias. Los usuarios pueden implementar un modelo de arrendamiento para la duración de instancias, similar al de .NET Framework Remoting. Esto se puede hacer mediante las interfaces de duración de contexto de instancias.
Control de errores personalizado. Los usuarios pueden controlar cómo se procesan los errores locales y cómo se devuelven los errores a los clientes. Esto se puede implementar utilizando las interfaces IErrorHandler.
Comportamientos de autorización personalizados. Los usuarios pueden implementar un control de acceso personalizado extendiendo las partes en tiempo de ejecución de contratos u operaciones y agregando comprobaciones de seguridad basadas en los tokens presentes en el mensaje. Esto se puede lograr utilizando las interfaces del interceptor de mensajes o del interceptor de parámetros. Para obtener ejemplos, vea Security Extensibility Samples.
Precaución:
Dado que modificar las propiedades de seguridad puede poner en peligro la seguridad de las aplicaciones de WCF, se recomienda encarecidamente que lleve a cabo con mucho cuidado las modificaciones relacionadas con la seguridad y las pruebe antes de realizar la implementación. Validadores personalizados de WCF en tiempo de ejecución. Puede instalar validadores personalizados que examinen servicios, contratos y enlaces para exigir directivas de empresa con respecto a aplicaciones de WCF. (Para obtener un ejemplo, vea Cómo bloquear extremos en la empresa).
Uso de la clase DispatchRuntime
Utilice la clase DispatchRuntime para modificar el comportamiento predeterminado de extremo individual o de servicio, o para insertar objetos que implementen modificaciones personalizadas en uno o ambos de los siguientes procesos de servicio (o procesos de cliente en el caso de un cliente dúplex):
- La transformación de mensajes entrantes en los objetos y la suelta de esos objetos como invocaciones de método en un objeto de servicio.
- La transformación de objetos recibidos de la respuesta a una invocación de operación de servicio en mensajes salientes.
DispatchRuntime le permite interceptar y extender el canal o el distribuidor del extremo para todos los mensajes de un contrato determinado, incluso cuando no se reconoce un mensaje. Cuando llega un mensaje que no coincide con ningún mensaje declarado en el contrato, se envía a la operación devuelta por la propiedad UnhandledDispatchOperation. Para interceptar o extenderse por todos los mensajes de una operación determinada, vea la clase DispatchOperation.
Hay cuatro áreas principales de extensibilidad del distribuidor expuestas por la clase DispatchRuntime:
- Los componentes de canal utilizan las propiedades de DispatchRuntime y las del distribuidor del canal asociado devueltas por la propiedad ChannelDispatcher para personalizar cómo el distribuidor del canal acepta y cierra los canales. Esta categoría incluye las propiedades ChannelInitializers y InputSessionShutdownHandlers.
- Los componentes de mensaje se personalizan para cada mensaje procesado. Esta categoría incluye las propiedades MessageInspectors, OperationSelector, Operations y ErrorHandlers.
- Los componentes de instancia personalizan la creación, duración y eliminación de instancias del tipo de servicio. Para obtener más información acerca de la duración de los objetos de servicio, vea la propiedad InstanceContextMode. Esta categoría incluye las propiedades InstanceContextInitializers y InstanceProvider.
- Los componentes relacionados con seguridad pueden utilizar las propiedades siguientes:
- SecurityAuditLogLocation indica donde se escriben los eventos de auditoría.
- ImpersonateCallerForAllOperations controla si el servicio intenta suplantar mediante las credenciales proporcionadas por el mensaje entrante.
- MessageAuthenticationAuditLevel controla si los eventos de autenticación de mensajes correctos se escriben en el registro de eventos especificado por SecurityAuditLogLocation.
- PrincipalPermissionMode controla cómo se establece la propiedad CurrentPrincipal.
- ServiceAuthorizationAuditLevel especifica cómo se realiza la auditoría de eventos de autorización.
- SuppressAuditFailure especifica si suprimir excepciones no críticas que producen durante el proceso del registro.
Normalmente, un comportamiento de servicio (un objeto que implementa IServiceBehavior), un comportamiento de contrato (un objeto que implementa IContractBehavior) o un comportamiento de extremo (un objeto que implementa IEndpointBehavior) pueden asignar objetos de extensión a una propiedad DispatchRuntime o insertarlos en una colección. Entonces, el objeto de comportamiento de instalación se agrega a la colección adecuada de comportamientos mediante programación o implementando un objeto BehaviorExtensionElement personalizado para permitir insertar el comportamiento con un archivo de configuración de la aplicación.
Los clientes dúplex (clientes que implementan un contrato de devolución de llamadas especificado por un servicio dúplex) también tienen un objeto DispatchRuntime al que se puede obtener acceso usando la propiedad CallbackDispatchRuntime.
Uso de la clase DispatchOperation
La clase DispatchOperation es la ubicación para las modificaciones en tiempo de ejecución y el punto de inserción para las extensiones personalizadas cuyo ámbito es sólo una operación de servicio. (Para modificar el comportamiento del tiempo de ejecución del servicio para todos los mensajes de un contrato, use la clase DispatchRuntime.)
Instale las modificaciones de DispatchOperation utilizando un objeto de comportamiento del servicio personalizado.
Use la propiedad Operations para buscar el objeto DispatchOperation que representa una operación de servicio determinada.
Las siguientes propiedades controlan la ejecución en tiempo de ejecución en el nivel de operación:
- Las propiedades Action, ReplyAction, FaultContractInfos, IsOneWay, IsTerminating y Name obtienen los valores correspondientes para la operación.
- Las propiedades TransactionAutoComplete y TransactionRequired especifican el comportamiento de transacciones.
- Las propiedades ReleaseInstanceBeforeCall y ReleaseInstanceAfterCall controlan la duración del objeto de servicio definido por el usuario relativo a InstanceContext.
- Las propiedades DeserializeRequest, SerializeReplyy Formatter habilitan el control explícito sobre la conversión de los mensajes en los objetos, y de los objetos en mensajes.
- La propiedad Impersonation especifica el nivel de suplantación de la operación.
- La propiedad CallContextInitializers inserta extensiones de contexto de llamada personalizadas para la operación.
- La propiedad AutoDisposeParameters controla cuando se destruyen los objetos de parámetro.
- La propiedad Invoker se usa para insertar un objeto autor de llamada personalizado.
- La propiedad ParameterInspectors permite insertar un inspector de parámetros personalizado que se puede utilizar para inspeccionar o modificar parámetros y valores devueltos.
Consulte también
Tareas
Cómo: Inspeccionar y modificar mensajes en el servicio
Cómo: inspeccionar o modificar parámetros
Cómo bloquear extremos en la empresa