Я хочу генерировать "сильные" типы на основе "слабо" типизированных источников данных, используя механизм провайдера типа F # 3.0. Сгенерированные типы должны быть доступны из клиентов С# в среде, где установлен только .Net 4.0, но не .Net 4.5. Если совместимость .Net 4.0 невозможна, мы не можем использовать поставщиков типов в нашем текущем крупномасштабном проекте ERP.
До сих пор мне удалось создать MyGeneratedTypes.dll, выполнив учебник в msdn (раздел "Предоставление сгенерированных типов" ), используя ProvidedTypeDefinition
из "ProvidedTypes-0.2.fs", который является частью пакета образцов F # 3.0. (Чтобы он работал, мне пришлось удалить строку "File.Delete
..." из метода "ProvidedTypeDefinition.ConvertToGenerated
..." ).
MyGeneratedTypes.dll имеет версию исполнения v4.0.30319, которая в порядке (время выполнения .Net 4.0). Я могу добавить ссылку на MyGeneratedTypes.dll в приложение С#/Net 4.0, а IntelliSense отображает типы и члены как ожидалось. Однако, когда я пытаюсь скомпилировать, компилятор С# выходит из строя и выдает предупреждение MSB3258: первичная ссылка "MyGeneratedTypes" не может быть решена, поскольку она имеет косвенную зависимость от сборки .NET Framework "FSharp.Core, Version = 4.3.0.0, Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a", который имеет более высокую версию "4.3.0.0", чем версия "4.0.0.0" в текущей целевой структуре.
Взгляд на IL Spy подтверждает, что MyGeneratedTypes.dll действительно содержит ссылку на FSharp.Core 4.3, хотя эта ссылка совершенно не нужна. До сих пор я не нашел способа предотвратить компилятор F # от ввода этой ссылки в сгенерированную сборку. (Помимо прочего, я создал чистую сборку .Net 4.0 в С# и передал ее конструктору ProvidedTypeDefinition
, но это не повлияло).
Кто-нибудь знает: а) как избавиться от ссылки, или б) если это только проблема с выпуском релиза F # 3.0, которая будет решена в финальной версии.
Edit
Разговор с @Brian привел к следующему "частичному" решению проблемы: вы можете скомпилировать "чистый С#/Net 4.0" клиент, ссылающийся на библиотеку с генерируемыми типами F # 3.0, но только путем вызова .Net 4.0 С# (csc) непосредственно из командной строки. Он не работает при компиляции в VS 2010 или в командной строке MSBuild. Я подозреваю, что это вызвано следующим поведением:
- MyGeneratedTypes.dll генерируется в VS 2012 с механизмом поставщика типа F #.
- Во время генерации ссылка на FSharp.Core 4.3 автоматически добавляется (даже если это не требуется) без указания в метаданных для зависимостей "SpecificVersion: true".
- Клиент С# в VS 2010 на системной ссылке ".Net 4.5 бесплатно" MyGeneratedTypes.dll.
- Когда клиент С# компилируется, MSBuild обнаруживает косвенную ссылку на FSharp.Core 4.3 внутри MyGeneratedTypes.dll.
- Поскольку косвенная ссылка существует с "SpecificVersion: false", MSBuild выдает предупреждение MSB3257 и отказывается передать прямую ссылку /r: "MyGeneratedTypes.dll" компилятору С# (csc). (Примечание: предупреждения MSBuild не могут быть подавлены каким-либо образом.)
- Компилятор С# (csc) вызывается MSBuild без /r: "MyGeneratedTypes.dll". Поэтому он не может скомпилировать и испускать ошибку компилятора CS0246: "Тип или имя пространства имен" MyGeneratedTypes "не удалось найти (...)".
Насколько я могу судить, мы застряли в этой проблеме, если механизм поставщика типа F # не изменился либо a), чтобы исключить ref для FSharp.Core 4.3, когда он не нужен в сгенерированной сборке, или b) включить ref с метаданными "SpecificVersion:true
".