configurar wcf app-config endpoints base-address

configurar - ¿Pueden varios servicios WCF compartir una BaseAddress común?



configurar binding wcf (3)

Tengo una asamblea que contiene varios servicios de WCF, cada uno con su propio contrato. Todo funciona bien. La configuración del servicio en el app.config para el servicio se ve así:

<services> <service behaviorConfiguration="WcfService.AlyzaServiceBehavior" name="Sam.Alyza.WcfService.ServiceWebsites"> <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Websites/" /> </baseAddresses> </host> </service> <service behaviorConfiguration="Sam.Alyza.WcfService.LogReaderServiceBehavior" name="Sam.Alyza.WcfService.ServiceLogReader"> <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/LogReader/" /> </baseAddresses> </host> </service> <service behaviorConfiguration="Sam.Alyza.WcfService.ServiceSystemverwaltungBehavior" name="Sam.Alyza.WcfService.ServiceSystemverwaltung"> <endpoint address="" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/Systemverwaltung/" /> </baseAddresses> </host> </service> [...] </services>

Como tengo un proyecto más grande en mente, con más contratos, me gustaría tener una forma de compartir la BaseAddress entre los diferentes contratos de servicio.
Si esto fuera solo un servicio con diferentes contratos y puntos finales, podría establecer una dirección base ommon, pero ¿cómo configuro una dirección base común para más de un servicio?

Por supuesto, necesitaría algo similar para el cliente.


Los servicios pueden compartir los valores BaseAddress (incluidos los números de puerto, si el servicio Net.Tcp Port Sharing se está ejecutando). Son las direcciones de punto final las que deben ser únicas. Observe en su archivo de configuración que los puntos finales MEX para cada ServiceHost tienen una dirección de "mex". Sus otros puntos finales tienen una dirección de cadena vacía. Cuando proporciona una dirección relativa para un punto final a WCF (al menos en el archivo de configuración), se antepone a la dirección base. Por lo tanto, la dirección del punto final MEX para el servicio LogReader es "net.tcp: // localhost: 8731 / Design_Time_Addresses / SamAlyza / LogReader / mex".

Como no se estableció una dirección relativa en el punto final del servicio principal, la dirección base de ServiceHost se usa como la dirección real para el punto final del servicio principal. Dado que no hay dos puntos finales que puedan superponerse a los valores de Uri.AbsolutePath, su ejemplo lo llevará a creer que los valores de la dirección base no se pueden compartir. La clase ServiceHost que aloja servicios WCF no tiene un punto final integrado, mientras que la clase ServiceEndpoint tiene una propiedad ListenUri que se completará en función de la configuración que proporcione.

Si cambia los valores de BaseAddress en su ejemplo para todas las coincidencias, siempre que establezca valores de dirección relativa únicos en los elementos del Endpoint, todo debería funcionar. Sin embargo, parece que puede encontrarse con algunos desafíos con los puntos finales MEX, ya que todos ellos tienen la dirección "mex" actualmente. Hazlos únicos y deberías estar bien.

Ahora, debo preguntar, ¿está seguro de que no solo quiere que estos servicios compartan un espacio de nombres, en lugar de direcciones base?


Puede combinar todos los contratos en una clase, por lo que tiene un servicio con una dirección base y uno (o más) puntos finales por contrato.

Para evitar tener un gran archivo de clase, puede usar la palabra clave parcial (asumiendo que usa c #) para dividir la clase en varios archivos. Cada archivo puede implementar un contrato, lo que hace que el mantenimiento de las interfaces individuales sea mucho más fácil.

En C ++ puedes usar #includes o multiple inheritance, pero eso implica una gran cantidad de disciplina ...

Tu configuración se vería así:

<services> <service behaviorConfiguration="WcfService.AlyzaServiceBehavior" name="Sam.Alyza.WcfService.ServiceAll"> <endpoint address="Websites/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceWebsites"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="LogReader/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceLogReader"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="Systemverwaltung/" binding="netTcpBinding" contract="Sam.Alyza.WcfInterface.IServiceSystemverwaltung"> <identity> <dns value="localhost" /> </identity> </endpoint> <endpoint address="mex" binding="mexTcpBinding" contract="IMetadataExchange" /> <host> <baseAddresses> <add baseAddress="net.tcp://localhost:8731/Design_Time_Addresses/SamAlyza/" /> </baseAddresses> </host> </service> </services>


También puede establecer las direcciones base en el código si usa un ServiceHostFactory personalizado.

En config puedes tener alguna configuración de aplicación:

<configuration> <appSettings> <add key="BaseAddress" value="http://localhost:1234" /> </appSettings> <configuration>

Luego crea un ServiceHostFactory personalizado:

public sealed class MyServiceHostFactory : ServiceHostFactory { protected override ServiceHost CreateServiceHost(Type serviceType, Uri[] baseAddresses) { var baseAddy = ConfigurationManager.AppSettings["BaseAddress"]; baseAddresses.Add(new Uri(baseAddy)); return new ServiceHost(serviceType, baseAddresses); } }

Luego también debe cambiar sus archivos .svc para usar esa fábrica:

<%@ ServiceHost Language="C#" Debug="true" Service="MyApp.MyService" CodeBehind="MyService.svc.cs" Factory="MyApp.MyServiceHostFactory" %>