Jak wygenerować przyjazne dla C # typy zgodne z .Net 4.0 przy użyciu dostawców typu F # 3.0
Chcę generować „silne” typy w oparciu o „słabo” typowane źródła danych, używając mechanizmu dostawcy typu F # 3.0. Wygenerowane typy muszą być dostępne z klientów C # w środowisku, w którym zainstalowany jest tylko .Net 4.0, ale nie .Net 4.5. Jeśli kompatybilność z .Net 4.0 nie jest możliwa, nie możemy używać dostawców typu w naszym obecnym projekcie ERP na dużą skalę.
Do tej pory udało mi się utworzyć MyGeneratedTypes.dll, postępując zgodnie zseminarium w msdn (sekcja „Udostępnianie wygenerowanych typów”), używającProvidedTypeDefinition
z „ProvidedTypes-0.2.fs”, który jest częścią pakietu próbek F # 3.0. (Aby działał, musiałem usunąć linię ”File.Delete
... „z”ProvidedTypeDefinition.ConvertToGenerated
..." metoda).
MyGeneratedTypes.dll ma wersję wykonawczą v4.0.30319, która jest OK (środowisko wykonawcze .Net 4.0). Mogę dodać odwołanie do MyGeneratedTypes.dll w aplikacji C # /. Net 4.0, a IntelliSense pokazuje typy i członków zgodnie z oczekiwaniami. Jednak przy próbie kompilacji kompilator C # kończy się niepowodzeniem i generuje „ostrzeżenie MSB3258: Nie można rozwiązać podstawowego odwołania„ MyGeneratedTypes ”, ponieważ ma on zależność pośrednią od zespołu .NET Framework„ FSharp.Core, Version = 4.3.0.0 , Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a ”, który ma wyższą wersję„ 4.3.0.0 ”niż wersja„ 4.0.0.0 ”w bieżącej strukturze docelowej.”
Spojrzenie na IL Spy potwierdza, że MyGeneratedTypes.dll rzeczywiście zawiera odniesienie do FSharp.Core 4.3, mimo że to odniesienie jest całkowicie niepotrzebne. Jak dotąd nie znalazłem sposobu, aby uniemożliwić kompilatorowi F # umieszczenie tego odwołania w wygenerowanym zespole. (Między innymi stworzyłem czysty zespół .Net 4.0 w C # i przekazałem go konstruktorowiProvidedTypeDefinition
, ale to nie ma wpływu).
Czy ktoś wie a) jak pozbyć się odniesienia, lub b) czy jest to tylko problem z kandydatem do wydania F # 3.0, który zostanie rozwiązany w ostatecznej wersji.
Edytować
Rozmowa z @Brian doprowadziła do następującego „częściowego” rozwiązania problemu: Tymogą skompiluj klienta „czystego C # /. Net 4.0” odwołującego się do biblioteki z generowanymi typami F # 3.0, ale tylko przez wywołanie kompilatora .Net 4.0 C # (csc) bezpośrednioz linii poleceń. Nie działa podczas kompilacji w VS 2010 lub za pomocą wiersza poleceń MSBuild. Podejrzewam, że wynika to z następującego zachowania:
MyGeneratedTypes.dll jest generowany w VS 2012 z mechanizmem dostawcy typu F #.Podczas generacji automatycznie wstawiane jest odwołanie do FSharp.Core 4.3 (nawet jeśli nie jest potrzebne), bez określania „SpecificVersion: true” w metadanych zależności.Klient C # w VS 2010 na systemie „.Net 4.5-free” odwołuje się do MyGeneratedTypes.dll.Po skompilowaniu klienta C #, MSBuild odkrywa pośrednie odniesienie do FSharp.Core 4.3 wewnątrz MyGeneratedTypes.dll.Ponieważ pośrednie odwołanie istnieje z „SpecificVersion: false”, MSBuild wysyła ostrzeżenieMSB3257 i odmawia przekazania bezpośredniego odwołania /r:"MyGeneratedTypes.dll ”do kompilatora C # (csc). (Uwaga: ostrzeżeń MSBuild nie można w żaden sposób ukryć).Kompilator C # (csc) jest wywoływany przez MSBuild, bez /r:"MyGeneratedTypes.dll ”. Dlatego nie może się skompilować i emituje błąd kompilatora CS0246: „Nie można znaleźć typu lub przestrzeni nazw„ MyGeneratedTypes ”(...)”.O ile mogę powiedzieć, utknęliśmy z tym problemem, chyba że mechanizm dostawcy typu F # zostanie zmodyfikowany a), aby wykluczyć ref do FSharp.Core 4.3, gdy nie jest on potrzebny w wygenerowanym zespole, lub b) do włączenia ref z metadanymi ”SpecificVersion:true
„