Domanda

Sto riscontrando un problema relativo agli spazi dei nomi utilizzati dai miei riferimenti di servizio. Ho un numero di servizi WCF, diciamo con lo spazio dei nomi MyCompany.Services.MyProduct ( gli spazi dei nomi effettivi sono più lunghi ).
Come parte del prodotto, sto anche fornendo un sito Web C # .NET di esempio. Questa applicazione Web utilizza lo spazio dei nomi MyCompany.MyProduct.

Durante lo sviluppo iniziale, il servizio è stato aggiunto come riferimento di progetto al sito Web e lo utilizza direttamente. Ho usato un modello di fabbrica che restituisce un'istanza di oggetto che implementa MyCompany.Services.MyProduct.IMyService. Fin qui tutto bene.

Ora voglio cambiarlo per usare un riferimento effettivo al servizio. Dopo aver aggiunto il riferimento e digitato using nella casella di testo dello spazio dei nomi, genera le classi nello spazio dei nomi MyCompany.MyProduct.MyCompany.Services.MyProduct . BAD! Non voglio cambiare global:: direttive in diversi posti solo perché sto usando una classe proxy. Quindi ho provato a anteporre lo spazio dei nomi con MyCompany, ma questo non è accettato.

Notare che non avevo ancora eliminato i riferimenti di assieme originali e " riutilizzare i tipi " è abilitato, ma apparentemente non è stato fatto alcun riutilizzo. Tuttavia, non voglio mantenere i riferimenti dell'assembly nel mio sito Web di esempio affinché funzioni comunque .

L'unica soluzione che ho trovato finora è impostare lo spazio dei nomi predefinito per la mia applicazione Web su Services.MyProduct (perché non può essere vuoto) e aggiungere il riferimento al servizio come OtherCompany.Whatever. Supponiamo che un cliente desideri utilizzare il mio sito Web di esempio come punto di partenza e che cambi lo spazio dei nomi predefinito in <=>, ciò ovviamente interromperà la mia soluzione alternativa.

Esiste una buona soluzione a questo problema?

Per riassumere : desidero generare un proxy di riferimento del servizio nello spazio dei nomi originale, senza fare riferimento all'assembly.

Nota: ho visto questa domanda , ma non è stata fornita alcuna soluzione accettabile per il mio caso d'uso.


Modifica: come suggerito da John Saunders, ho inviato un feedback a Microsoft su questo:
Elemento di feedback @ Microsoft Connect

È stato utile?

Soluzione

Ho aggiunto un write- di questa soluzione al mio blog. Le stesse informazioni in realtà, ma forse un po 'meno frammentate

Ho trovato un'alternativa all'utilizzo di svcutil.exe per ottenere ciò che voglio. (Imo) semplifica l'aggiornamento del riferimento al servizio piuttosto che rieseguire l'utilità.

È necessario specificare esplicitamente un uri dello spazio dei nomi su ServiceContract e DataContracts ( vedere più avanti per un commento ).

[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
}

Lo spazio dei nomi potrebbe essere qualsiasi cosa, ma tecnicamente deve essere un uri valido, quindi ho scelto questo schema. Potrebbe essere necessario compilare manualmente affinché le cose funzionino in seguito, quindi fallo.

Al termine, abilita l'opzione Mostra tutti i file in Esplora soluzioni. Espandi il riferimento al servizio che hai aggiunto in precedenza. Fare doppio clic sul Reference.svcmap file.

Ci sarà un elemento <NamespaceMappings />, che dovrai modificare. Continuando il mio esempio:

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

Salva il file, fai clic con il tasto destro del mouse sul riferimento del servizio e seleziona Aggiorna riferimento al servizio .

Puoi aggiungere tutte le mappature di cui hai bisogno (ne avevo effettivamente bisogno due). L'effetto è lo stesso dell'approccio svcutil /namespace:, ma senza dover utilizzare la riga di comando util stessa, facilitando l'aggiornamento.

Differenza con svcutil

L'aspetto negativo di questo approccio è che è necessario utilizzare i mapping espliciti dello spazio dei nomi. Usando svcutil, hai la possibilità di mappare tutto ciò che non è stato esplicitamente mappato in questo modo (la soluzione a cui John Saunders si riferiva):

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

Potresti pensare di usare:

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

ma questo non funzionerà, perché Visual Studio aggiunge già implicitamente questa mappatura, indicando il nome dello spazio dei nomi generato che stiamo cercando di eliminare. La configurazione precedente farà sì che Visual Studio si lamenti di una chiave duplicata.

Spazi dei nomi espliciti dell'annuncio :
Quando nel tuo codice non viene specificato lo spazio dei nomi di exploit, sembra che .NET genererà un uri del modulo http://schemas.datacontract.org/2004/07/MyCompany.Services.MyProduct . Potresti mappare sia gli spazi dei nomi espliciti nel mio esempio, ma non so se ci sono garanzie per questo comportamento. Pertanto, andare con uno spazio dei nomi esplicito potrebbe essere migliore.

NB: la mappatura di due TargetNamespace sullo stesso ClrNamespace sembra interrompere la generazione del codice

Altri suggerimenti

Il tuo caso d'uso era sbagliato.

Non avresti mai dovuto includere il servizio come riferimento in primo luogo.

Credo che svcutil.exe accetterà un interruttore che specifica l'intero spazio dei nomi da usare.

In VS2010 e versioni successive c'è un modo per impostare spazi dei nomi personalizzati. In Esplora soluzioni, seleziona & Quot; Mostra tutti i file & Quot; quindi apri " Riferimenti web " nella struttura della soluzione selezionare il servizio, selezionare il nodo Reference.map, mostrare le proprietà e impostare la proprietà dello spazio dei nomi dello strumento personalizzato.

Purtroppo non ho abbastanza reputazione per mostrare uno screenshot.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top