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:
- MyGeneratedTypes.dll viene generato in VS 2012 con il meccanismo del provider di tipo F #.
- Durante generazione, viene inserito automaticamente un riferimento FSharp.Core 4.3 (anche se non necessario), senza specificare "SpecificVersion: true" nei metadati per la dipendenza.
- Un client C# in VS 2010 su un sistema ".Net 4.5-free" fa riferimento a MyGeneratedTypes.dll.
- Quando il cliente # C viene compilato, MSBuild scopre il riferimento indiretto alla FSharp.Core 4.3 all'interno MyGeneratedTypes.dll.
- 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.)
- 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
".
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 # ... –
@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. –