2012-06-20 10 views
10

voglio generare tipi "forti" sulla base di "debolmente" tipizzato fonti di dati, utilizzando il meccanismo di F # 3.0 tipo di provider. I tipi generati devono essere accessibili dai client C# in un ambiente in cui sia installato .Net 4.0, ma non .Net 4.5. Se la compatibilità con .Net 4.0 non è possibile, non possiamo usare i provider di tipi nel nostro attuale progetto ERP su larga scala.Come generare C# -friendly, .Net 4.0 tipi compatibili utilizzando F # 3.0 Tipo fornitori

Finora, sono riuscito a creare MyGeneratedTypes.dll seguendo la tutorial su MSDN (sezione "Fornire tipi generati"), utilizzando il ProvidedTypeDefinition da "ProvidedTypes-0.2.fs", che fa parte del campione F # 3.0 confezione. (Per poter funzionare, ho dovuto rimuovere la riga "File.Delete ..." dal metodo "ProvidedTypeDefinition.ConvertToGenerated ...").

MyGeneratedTypes.dll ha runtime versione v4.0.30319, che è OK (il runtime di .Net 4.0). Posso aggiungere un riferimento a MyGeneratedTypes.dll in un'applicazione C# /. Net 4.0 e IntelliSense mostra i tipi e i membri come previsto. Tuttavia, quando provo a compilare, il compilatore C# fallisce e produce 'warning MSB3258: il riferimento primario "MyGeneratedTypes" non può essere risolto perché ha una dipendenza indiretta sull'assembly .NET Framework "FSharp.Core, Versione = 4.3.0.0 , Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a "che ha una versione superiore" 4.3.0.0 "rispetto alla versione" 4.0.0.0 "nel framework di destinazione corrente."

Uno sguardo a IL Spy conferma che MyGeneratedTypes.dll contiene effettivamente un riferimento a FSharp.Core 4.3, anche se questo riferimento non è necessario. Finora, non ho trovato modo di impedire al compilatore F # di inserire questo riferimento nell'assieme generato. (Tra le altre cose, ho creato un assembly .Net 4.0 puro in C# e l'ho passato al costruttore di ProvidedTypeDefinition, ma questo non ha alcuna influenza).

Qualcuno sa a) come sbarazzarsi di riferimento, oppure b) se si tratta solo di un problema di release candidate # 3.0 F, che verrà risolto nella versione finale.

Modifica

La conversazione con @ Brian ha portato alla seguente soluzione "parziale" per il problema: È può compilare una "puro C#/Net 4.0" cliente fa riferimento a una biblioteca con F # 3.0 tipi generati, ma solo chiamando il compilatore .Net 4.0 C# (csc) direttamente dalla riga di comando. Non funziona durante la compilazione in VS 2010 o tramite la riga di comando di MSBuild. Sospetto che ciò sia causato dal seguente comportamento:

  1. MyGeneratedTypes.dll viene generato in VS 2012 con il meccanismo del provider di tipo F #.
  2. Durante generazione, viene inserito automaticamente un riferimento FSharp.Core 4.3 (anche se non necessario), senza specificare "SpecificVersion: true" nei metadati per la dipendenza.
  3. Un client C# in VS 2010 su un sistema ".Net 4.5-free" fa riferimento a MyGeneratedTypes.dll.
  4. Quando il cliente # C viene compilato, MSBuild scopre il riferimento indiretto alla FSharp.Core 4.3 all'interno MyGeneratedTypes.dll.
  5. Poiché il riferimento indiretto esiste con "SpecificVersion: false", MSBuild emette l'avviso MSB3257 e rifiuta di passare il riferimento diretto /r:"MyGeneratedTypes.dll "al compilatore C# (csc). (Nota: MSBuild avvertimenti non possono essere soppressi in alcun modo.)
  6. Il compilatore C# (csc) viene chiamato da MSBuild, senza /r:"MyGeneratedTypes.dll".Pertanto, non può compilare ed emettere l'errore del compilatore CS0246: "Impossibile trovare il tipo o il nome dello spazio dei nomi 'MyGeneratedTypes' (...)".

Per quanto posso dire, siamo bloccati con questo problema a meno che il meccanismo di F # prestatore tipo viene modificato sia a) di escludere l'arbitro per FSharp.Core 4.3 quando non è necessario in un assembly generato, o b) per includere il riferimento con i metadati "SpecificVersion:true".

+2

Non ho una risposta, ma sono curioso - perché vuoi usare i provider di tipo F # se vuoi usare la libreria da C#? Stai pensando di passare a F # in futuro? Perché altrimenti, usare CodeDOM o Roslyn potrebbe essere un modo più semplice per risolvere il problema. Penso che la maggior parte del valore dei provider di tipi provenga quando li consumi da F # ... –

+0

@Tomas Stiamo usando F # come lingua aggiuntiva nelle parti non-UI di una soluzione che consiste principalmente di molti progetti C#. Speravo che i provider di tipi offrissero un modo semplificato per creare un generatore di tipi CLI (utilizzando _F # quotations_ e l'API semplificata di _ProvidedTypeDefinition_). Finora, mi piace quello che vedo, ma non si compila con C# (ancora?). Per anni abbiamo utilizzato un generatore autonomo che produce file di codice sorgente C#, il che è una seccatura da mantenere. Analizzerò CodeDom e Roslyn se i provider di tipi non funzionano, grazie per il suggerimento. –

risposta

6

Basta aggiungere un riferimento a FSharp.Core 4.3.0.0 nel progetto C# (o ignorare l'avviso). Nonostante la strana convenzione sulla numerazione, FSharp.Core 4.3.0.0 non dipende da nulla in .Net 4.5, dipende solo da .Net 4.0.

+0

Ho già provato questo. Ad ogni modo, il compilatore C# fornisce due errori dicendo che non trova lo spazio dei nomi e il tipo nell'assembly generato, sebbene entrambi siano perfettamente visibili tramite C# IntelliSense (Non c'è alcun problema al tempo di codifica C#, solo al tempo di compilazione C#). L'unico altro messaggio del compilatore C# è l'avviso "riferimento F # interno", che è innocuo in base alla risposta. In IL Spy, l'assemblaggio sembra normale ad eccezione del riferimento F #. Se il riferimento interno F # non è la causa principale del problema, non so cos'altro potrebbe essere ... –

+2

Ok, sarebbe utile condividere gli errori del compilatore che stai ottenendo. Quindi stai dicendo che ildasm/ilspy vede che questi tipi pubblici appaiono nell'assemblaggio di F #, ma per qualche motivo il compilatore C# non li "vede", anche se l'assembly fa riferimento a "/ r" sul csc.exe riga di comando? – Brian

+0

Sì, questo è quello che sto dicendo. Il client C# /. Net 4.0 funziona bene su Windows 8 in cui .Net 4.5 esiste. Tuttavia, non funziona su Windows 7 in cui esiste solo .Net 4.0. Qui, il compilatore C# emette due messaggi: 1) 'errore CS0246: non è stato possibile trovare il tipo o il nome dello spazio dei nomi' MyGeneratedTypes '(ti manca una direttiva using o un riferimento di assembly?)', E 2) l'avviso come menzionato in la domanda. La cosa strana è che all'interno di VS 2010 su Windows 7, C# IntelliSense riconosce il tipo e nessun problema viene segnalato da C# IDE o ReSharper. Semplicemente non si compila. –

Problemi correlati