Pregunta

Tengo un problema con respecto a los espacios de nombres utilizados por mis referencias de servicio. Tengo varios servicios WCF, por ejemplo, con el espacio de nombres MyCompany.Services.MyProduct ( los espacios de nombres reales son más largos ).
Como parte del producto, también proporciono un ejemplo de sitio web C # .NET. Esta aplicación web utiliza el espacio de nombres MyCompany.MyProduct.

Durante el desarrollo inicial, el servicio se agregó como referencia de proyecto al sitio web y se usa directamente. Usé un patrón de fábrica que devuelve una instancia de objeto que implementa MyCompany.Services.MyProduct.IMyService. Hasta ahora, todo bien.

Ahora quiero cambiar esto para usar una referencia de servicio real. Después de agregar la referencia y escribir using en el cuadro de texto del espacio de nombres, genera clases en el espacio de nombres MyCompany.MyProduct.MyCompany.Services.MyProduct . ¡MALO! No quiero tener que cambiar las directivas global:: en varios lugares solo porque estoy usando una clase proxy. Así que intenté anteponer el espacio de nombres con MyCompany, pero eso no es aceptado.

Tenga en cuenta que aún no había eliminado las referencias de ensamblaje originales y " reutilice los tipos " está habilitado, pero aparentemente no se volvió a utilizar. Sin embargo, no quiero mantener las referencias de ensamblaje en mi sitio web de muestra para que funcione de todos modos .

La única solución que he encontrado hasta ahora es establecer el espacio de nombres predeterminado para mi aplicación web en Services.MyProduct (porque no puede estar vacío) y agregar la referencia de servicio como OtherCompany.Whatever. Supongamos que un cliente quiere usar mi sitio web de muestra como punto de partida y cambia el espacio de nombres predeterminado a <=>, esto obviamente interrumpirá mi solución.

¿Existe una buena solución para este problema?

Para resumir : deseo generar un proxy de referencia de servicio en el espacio de nombres original, sin hacer referencia al ensamblado.

Nota: He visto esta pregunta , pero no se proporcionó ninguna solución que sea aceptable para mi caso de uso.


Editar: como sugirió John Saunders, he enviado algunos comentarios a Microsoft sobre esto:
Artículo de comentarios en Microsoft Connect

¿Fue útil?

Solución

He agregado un write- arriba de esta solución a mi blog. La misma información realmente, pero quizás un poco menos fragmentada

He encontrado una alternativa al uso de svcutil.exe para lograr lo que quiero. (Imo) hace que actualizar la referencia del servicio sea más fácil que volver a ejecutar la utilidad.

Debe especificar explícitamente una uri de espacio de nombres en su ServiceContract y DataContracts ( vea más abajo para comentarios ).

[ServiceContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public interface IService
{
    [OperationContract]
    CompositeType GetData();
}

[DataContract(Namespace = "http://company.com/MyCompany.Services.MyProduct")]
public class CompositeType
{
    // Whatever
}

El espacio de nombres podría ser cualquier cosa, pero técnicamente debe ser un uri válido, así que elegí este esquema. Es posible que deba crear manualmente para que las cosas funcionen más tarde, así que hágalo.

Una vez hecho esto, habilite la opción Mostrar todos los archivos en el Explorador de soluciones. Expanda la referencia de servicio que agregó anteriormente. Haga doble clic en el archivo Reference.svcmap.

Habrá un elemento <NamespaceMappings />, que deberá editar. Continuando con mi ejemplo:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="http://company.com/MyCompany.Services.MyProduct"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>

Guarde el archivo, haga clic con el botón derecho en la referencia de servicio y seleccione Actualizar referencia de servicio .

Puede agregar tantas asignaciones como necesite (en realidad necesitaba dos). El efecto es el mismo que el enfoque svcutil /namespace:, pero sin tener que usar la línea de comando util, lo que facilita la actualización.

Diferencia con svcutil

La desventaja de este enfoque es que necesita utilizar asignaciones explícitas de espacio de nombres. Con svcutil, tiene la opción de asignar todo lo que no se ha asignado explícitamente de esta manera (la solución a la que se refería John Saunders):

svcutil /namespace:*,MyCompany.Services.MyProduct ...

Puede pensar en usar:

<NamespaceMappings>
    <NamespaceMapping
        TargetNamespace="*"
        ClrNamespace="MyCompany.Services.MyProduct" />
</NamespaceMappings>

pero esto no funcionará, porque Visual Studio ya agrega implícitamente esta asignación, señalando el nombre del espacio de nombres generado del que estamos tratando de deshacernos. La configuración anterior hará que Visual Studio se queje de una clave duplicada.

Espacios de nombres explícitos de anuncios :
Cuando no se especifica ningún espacio de nombre explotado en su código, parece que .NET generará una uri de la forma http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct . Podría asignar eso tan bien como los espacios de nombres explícitos en mi ejemplo, pero no sé si hay alguna garantía para este comportamiento. Por lo tanto, ir con un espacio de nombres explícito podría ser mejor.

NB: asignar dos espacios TargetNames al mismo ClrNamespace parece interrumpir la generación de código

Otros consejos

Su caso de uso fue incorrecto.

Nunca debería haber incluido el servicio como referencia en primer lugar.

Creo que svcutil.exe aceptará un interruptor que especifica el espacio de nombres completo para usar.

En VS2010 y versiones posteriores hay una manera de configurar espacios de nombres personalizados. En el explorador de soluciones, seleccione & Quot; Mostrar todos los archivos & Quot; luego abra " Referencias web " en el árbol de soluciones, seleccione el servicio, seleccione el nodo Reference.map, muestre las propiedades y establezca la propiedad Custom Tool Namespace.

Desafortunadamente no tengo suficiente reputación para mostrar una captura de pantalla.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top