example - WCF ChannelFactory vs generación de proxy
soap.net core example (6)
El proxy creará funciones asíncronas para las cuales es bueno.
Solo me pregunto bajo qué circunstancias preferiría generar un proxy de un servicio WCF cuando puede invocar llamadas utilizando ChannelFactory.
De esta forma, no tendrá que generar un proxy y preocuparse por regenerar un proxy cuando se actualice el servidor.
Gracias
Hay 3 formas básicas de crear un cliente WCF:
Deje que Visual Studio genere su proxy. Este código genera automáticamente que se conecta al servicio leyendo el WSDL. Si el servicio cambia por alguna razón, debes regenerarlo. La gran ventaja de esto es que es fácil de configurar: VS tiene un asistente y todo es automático. La desventaja es que confía en VS para hacer todo el trabajo por usted y así perder el control.
Use
ChannelFactory
con una interfaz conocida. Esto depende de que tenga interfaces locales que describan el servicio (el contrato de servicio). La gran ventaja es que puede gestionar el cambio mucho más fácilmente: aún tiene que volver a compilar y corregir los cambios, pero ahora no está regenerando el código, está haciendo referencia a las nuevas interfaces. Comúnmente, esto se usa cuando controlas tanto el servidor como el cliente, ya que ambos se pueden burlar mucho más fácilmente para las pruebas unitarias. Sin embargo, las interfaces se pueden escribir para cualquier servicio, incluso para REST, eche un vistazo a esta API de Twitter .Escriba su propio proxy: esto es bastante fácil de hacer, especialmente para los servicios REST, usando
HttpClient
oWebClient
. Esto le proporciona el control de grano más fino, pero a costa de una gran cantidad de API de servicio en cadenas. Por ejemplo:var content = new HttpClient().Get("http://yoursite.com/resource/id").Content;
- si cambian los detalles de la API, no encontrará un error hasta el tiempo de ejecución.
Personalmente, nunca me ha gustado la opción 1: confiar en el código generado automáticamente es complicado y pierde demasiado control. Además, a menudo crea problemas de serialización: termino con dos clases idénticas (una en el código del servidor, una generada automáticamente) que se puede alterar, pero es un problema.
La opción 2 debería ser perfecta, pero los canales son un poco limitantes, por ejemplo, pierden por completo el contenido de los errores de HTTP . Dicho esto, tener interfaces que describan el servicio es mucho más fácil de codificar y mantener.
Mi respuesta es una especie de resumen de las respuestas de Keith''s y Andrew Hare .
Si no controla el servidor, pero solo tiene proxy WSDL / URL-generate usando Visual Studio o svcutil. (Tenga en cuenta que Visual Studio a veces falla, cuando svcutil funciona mejor).
Cuando controlas el servidor y el cliente, comparte interfaces / contratos y llamas a ChannelFactory
.
No es solo una cuestión de tiempo ahorrado. El uso del proxy generado WSDL es peligroso porque si olvida actualizar la referencia del servicio puede dejar la solución en un estado incoherente. Todo compila pero el contrato de servicio está roto. Definitivamente sugiero usar ChannelFactory siempre que sea posible, le hará la vida mucho más fácil.
Una posible alternativa podría ser escribir un script de precompilación que llame a la utilidad SVCUtil para crear el proxy cada vez que construya su proyecto, pero de todos modos, ChannelFactory es mucho más limpio y elegante.
Para utilizar ChannelFactory<T>
, debe estar dispuesto a compartir conjuntos de contratos entre el servicio y el cliente. Si esto está bien con usted, entonces ChannelFactory<T>
puede ahorrarle algo de tiempo.
Uso ChannelFactory junto con el método MetadataResolver.Resolve. La configuración del cliente es una molestia, así que obtengo mi ServiceEndpoint del servidor.
Cuando utiliza ChannelFactory (Of T), T es el contrato original que puede obtener de una referencia en su proyecto o una instancia de contrato generado. En algunos proyectos, genere el código de una referencia de servicio porque no pude agregar una referencia al dll del contrato. Incluso puede generar un contrato de asincronización con la referencia de servicio y usar esa interfaz de contrato con ChannelFactory.
El principal objetivo de usar ChannelFactory para mí fue deshacerme de la información de configuración del cliente de WCF. En el código de ejemplo siguiente, puede ver cómo lograr un cliente WCF sin configuración.
Dim fixedAddress = "net.tcp://server/service.svc/mex"
Dim availableBindings = MetadataResolver.Resolve(GetType(ContractAssembly.IContractName), New EndpointAddress(fixedAddress))
factoryService = New ChannelFactory(Of ContractAssembly.IContractName)(availableBindings(0))
accesService = factoryService.CreateChannel()
En mi proyecto final, se comprueban los enlaces disponibles para usar net.tcp o net.pipe si están disponibles. De esa forma, puedo usar el mejor enlace disponible para mis necesidades. Solo me baso en el hecho de que existe un punto final de metadatos en el servidor.
espero que esto ayude
Por cierto, esto se hace usando .NET 3.5. Sin embargo, funciona también con 4.0.