2009-05-30 7 views
10

L'integrazione VS WCF ha una buona opzione "Riutilizza i tipi negli assembly con rifrazione". Il problema è che ho bisogno dello stesso ma per l'attuale assemblaggio. Alcuni tipi sono già definiti nel mio assieme e ho bisogno di riutilizzarli.Riutilizzare i tipi nell'assieme corrente per WCF Proxies

Scenario di utilizzo:

  1. ho assemblaggio, e hanno TypeA qui.
  2. Aggiungo il riferimento di servizio, e uno dei metodi restituisce un tipo completamente compatibile con TypeA (proprietà, nome).
  3. Aggiungi riferimento servizio genera proxy, ma ricreare nuovo TypeA all'interno.

Sul passaggio 3 ho bisogno del proxy che restituirà TypeA. Non nuovo TypeA.

+0

possibile duplicato del [ "riuso tipi esistenti" viene ignorata quando si aggiunge un riferimento al servizio] (http://stackoverflow.com/questions/134064/reuse-existing-types-is-ignored-when-adding-a-service-reference) –

risposta

12

Se capisco cosa si vuole fare, allora è uno scenario in cui mi imbatto e, beh, WCF ha una risposta decente a: Semplicemente non usare i wizard di riferimento del servizio SvcUtil/WS.

Se la maggior parte delle classi di contratto è già definita nel proprio client (sia perché si dispone di un assembly condiviso o perché sono definite classi equivalenti nel progetto), si potrebbe anche andare al passaggio successivo e o importa il contratto di servizio completo in forma di codice o semplicemente ridefinirlo sul lato client.

Non c'è niente che ti costringe a usare svcutil e gli amici, basta definire l'interfaccia e utilizzare il modello di canale direttamente (ChannelFactory <T> e amici), o, se si preferisce utilizzare le classi proxy, basta creare il proprio ClientBase T > -categoria precedente. È davvero molto semplice e ti farà risparmiare problemi a lungo termine.

+0

Sì, ho fatto in questo modo, leggermente dopo aver chiesto. Comunque grazie per il tuo tempo. –

0

Ho avuto lo stesso problema, per cui volevo un test harness per puntare a un paio di servizi. Ogni servizio avrebbe dati in comune in comune.

Che cosa deve essere fatto:

  1. Usa svcutil con/t: i metadati su ogni URL.
  2. rinominare tutti i file generati con qualcosa di unico per il servizio (ad esempio, Rinomina lala.xsd a 1_lala.xsd)
  3. Copiare tutti i file generati da una singola posizione
  4. Usa svcutil con * .xsd .wsdl/out : output.cs/namespace:, MySpecialNamespace per generare TUTTI i contratti di servizio e i contratti di dati in un singolo file.

Se si vuole essere furbo: utilizzare il seguente modello T4:

<#@ template language="C#v4.0" hostspecific="True"#> 
<#@ import namespace="System.Diagnostics" #> 
<#@ import namespace="System.IO" #> 
<#=GetGeneratedCode(
"http://localhost/Service/Service1.svc", 
"http://localhost/Service/Service2.svc", 
"http://localhost/Service/Service3.svc", 
"http://localhost/Service/Service4.svc" 
)#> 
<#+ 
const string _svcutil = @"C:\Program Files (x86)\Microsoft SDKs\Windows\v7.0A\Bin\svcutil.exe"; 

private string GetGeneratedCode(params string[] urls) 
{ 
    var tmp = GetTemporaryDirectory(); 
    foreach (var url in urls) 
    { 
     GetMetadata(url, tmp); 
    } 

    RunSvcutil(tmp, "*.wsdl *.xsd /out:output.cs /namespace:*," +  Path.GetFileNameWithoutExtension(Host.TemplateFile)); 
    var result = File.ReadAllText(Path.Combine(tmp, "output.cs")); 
    return result; 
} 

private static void RunSvcutil(string workingFolder, string arguments) 
{ 
    var processInfo = new ProcessStartInfo(_svcutil); 
    processInfo.Arguments = arguments; 
    processInfo.WorkingDirectory = workingFolder; 

    var p = Process.Start(processInfo); 
    p.WaitForExit(); 
} 

private static void GetMetadata(string url, string destination) 
{ 
    var workingFolder = GetTemporaryDirectory(); 
    RunSvcutil(workingFolder, string.Format("/t:metadata \"{0}\"", url)); 

    foreach (var filename in Directory.GetFiles(workingFolder)) 
    { 
     File.Copy(filename, Path.Combine(destination,  Path.GetFileNameWithoutExtension(url) + "_" + Path.GetFileName(filename))); 
    } 
} 

private static string GetTemporaryDirectory() 
{ 
    string tempDirectory = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); 
    Directory.CreateDirectory(tempDirectory); 
    return tempDirectory; 
} 
#> 
Problemi correlati