2012-06-20 8 views
10

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:

  1. MyGeneratedTypes.dll se genera en VS 2012 con el mecanismo de proveedor de tipo F #.
  2. 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.
  3. Un cliente de C# en VS 2010 en un sistema ".Net 4.5-free" hace referencia a MyGeneratedTypes.dll.
  4. Cuando se compila el cliente C#, MSBuild descubre la referencia indirecta a FSharp.Core 4.3 dentro de MyGeneratedTypes.dll.
  5. 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).
  6. 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".

+2

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 # ... –

+0

@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. –

Respuesta

6

Simplemente agregue una referencia a FSharp.Core 4.3.0.0 en el proyecto C# (o ignore la advertencia). A pesar de la extraña convención de numeración, FSharp.Core 4.3.0.0 no depende de nada en .Net 4.5, solo depende de .Net 4.0.

+0

Ya lo he intentado. De cualquier manera, el compilador C# da dos errores diciendo que no encuentra el espacio de nombres y el tipo en el ensamblado generado, aunque ambos son perfectamente visibles a través de C# IntelliSense (No hay problema en el tiempo de codificación C#, solo en el tiempo de compilación C#). El único otro mensaje del compilador C# es la advertencia de "referencia F # interna", que es inofensivo de acuerdo con su respuesta. En IL Spy, el conjunto parece normal, excepto por la referencia F #. Si la referencia interna de F # no es la causa raíz del problema, no sé qué más podría ser ... –

+2

Bien, sería útil compartir los errores reales del compilador que está obteniendo. Entonces dices que ildasm/ilspy ven que estos tipos públicos aparecen en el ensamblado F #, pero por alguna razón el compilador C# no los 've', aunque el ensamblado es referencia con '/ r' en csc.exe ¿línea de comando? – Brian

+0

Sí, eso es lo que estoy diciendo. El cliente C# /. Net 4.0 funciona bien en Windows 8 donde .Net 4.5 existe. Sin embargo, no funciona en Windows 7 donde solo existe .Net 4.0. Aquí, el compilador C# emite dos mensajes: 1) 'error CS0246: no se pudo encontrar el tipo o el nombre del espacio de nombres' MyGeneratedTypes '(¿falta una directiva using o una referencia de ensamblado?)', Y 2) la advertencia mencionada en la pregunta. Lo extraño es que dentro de VS 2010 en Windows 7, C# IntelliSense reconoce el tipo, y C# IDE o ReSharper no informan ningún problema. Simplemente no compila. –

Cuestiones relacionadas