Quiero generar tipos "fuertes" basados en fuentes de datos de tipo "débil", utilizando el mecanismo de proveedor de tipo F # 3.0. Los tipos generados deben ser accesibles desde clientes C# en un entorno donde solo se instala .Net 4.0, pero no .Net 4.5. Si la compatibilidad con .Net 4.0 no es posible, no podemos usar proveedores de tipo en nuestro proyecto actual de ERP a gran escala.Cómo generar tipos compatibles con C#, compatible con .NET 4.0 utilizando proveedores de tipo F # 3.0
Hasta el momento, han tenido éxito en la creación de MyGeneratedTypes.dll siguiendo el tutorial en MSDN (sección "Proporcionar Tipos generados"), mediante el ProvidedTypeDefinition
de "ProvidedTypes-0.2.fs", que forma parte de la muestra F # 3.0 paquete. (Para que funcione, tuve que eliminar la línea "File.Delete
..." del método "ProvidedTypeDefinition.ConvertToGenerated
...").
MyGeneratedTypes.dll tiene la versión de tiempo de ejecución v4.0.30319, que está bien (el tiempo de ejecución de .Net 4.0). Puedo agregar una referencia a MyGeneratedTypes.dll en una aplicación C# /. Net 4.0, e IntelliSense muestra los tipos y miembros como se esperaba. Sin embargo, cuando intento compilar, el compilador C# falla y produce 'MSB3258 de advertencia: la referencia primaria "MyGeneratedTypes" no se pudo resolver porque tiene una dependencia indirecta en el ensamblado de .NET Framework "FSharp.Core, Version = 4.3.0.0 , Culture = neutral, PublicKeyToken = b03f5f7f11d50a3a "que tiene una versión más alta" 4.3.0.0 "que la versión" 4.0.0.0 "en el marco de destino actual. '
Una mirada a IL Spy confirma que MyGeneratedTypes.dll de hecho contiene una referencia a FSharp.Core 4.3, aunque esta referencia es completamente innecesaria. Hasta ahora, no he encontrado manera de evitar que el compilador F # coloque esta referencia en el ensamblaje generado. (Entre otras cosas, he creado un ensamblado .NET 4.0 puro en C# y lo pasé al constructor de ProvidedTypeDefinition
, pero esto no tiene ninguna influencia).
¿Alguien sabe a) cómo deshacerse de la referencia, o b) si esto es solo un problema de lanzamiento de versión F # 3.0, que se resolverá en la versión final.
Editar
La conversación con @ Brian ha dado como resultado la siguiente solución "parcial" al problema: puede compilar una "pura C#/Net 4.0" cliente hace referencia a una biblioteca con F # 3.0 tipos generados, pero solo llamando al compilador .NET 4.0 C# (csc) directamente desde la línea de comandos. No funciona al compilar en VS 2010 o a través de la línea de comandos de MSBuild. Sospecho que esto es causado por el siguiente comportamiento:
- MyGeneratedTypes.dll se genera en VS 2012 con el mecanismo de proveedor de tipo F #.
- Durante la generación, se inserta automáticamente una referencia a FSharp.Core 4.3 (incluso si no es necesario), sin especificar "SpecificVersion: true" en los metadatos de la dependencia.
- Un cliente de C# en VS 2010 en un sistema ".Net 4.5-free" hace referencia a MyGeneratedTypes.dll.
- Cuando se compila el cliente C#, MSBuild descubre la referencia indirecta a FSharp.Core 4.3 dentro de MyGeneratedTypes.dll.
- Como existe la referencia indirecta con "SpecificVersion: false", MSBuild emite la advertencia MSB3257 y se niega a pasar la referencia directa /r:"MyGeneratedTypes.dll "al compilador de C# (csc). (Nota: las advertencias de MSBuild no se pueden suprimir de ninguna manera).
- El compilador de C# (csc) lo invoca MSBuild, sin /r:"MyGeneratedTypes.dll ".Por lo tanto, no puede compilar y emite el error de compilación CS0246: "No se pudo encontrar el tipo o el nombre del espacio de nombres 'MyGeneratedTypes' (...)".
Por lo que puedo decir, estamos atascados con este problema a menos que el mecanismo de proveedor de tipo F # se modifique a) para excluir la referencia a FSharp.Core 4.3 cuando no se necesita en un ensamblaje generado, o b) incluir la referencia con los metadatos "SpecificVersion:true
".
No tengo una respuesta, pero tengo curiosidad: ¿por qué quieres usar proveedores de tipo F # si vas a usar la biblioteca de C#? ¿Estás planeando mudarte a F # en el futuro? Porque si no, usar CodeDOM o Roslyn podría ser una forma más fácil de resolver el problema. Creo que la mayor parte del valor de los proveedores de tipo viene cuando los consumes desde F # ... –
@Tomas Estamos utilizando F # como lenguaje adicional en las partes de una solución que no son UI y que consiste principalmente en muchos proyectos de C#. Esperaba que los proveedores de tipos ofrecieran una forma simplificada de crear un generador de tipo CLI (utilizando _F # quotations_ y la API optimizada de _ProvidedTypeDefinition_). Hasta ahora, me gusta lo que veo, pero no se compila con C# (¿todavía?). Durante años, hemos estado utilizando un generador hecho a sí mismo que produce archivos de código fuente C#, lo cual es una tarea difícil de mantener. Buscaré en CodeDom y Roslyn si los proveedores de tipos no funcionan, gracias por la sugerencia. –