2012-06-20 38 views
10

Tôi muốn tạo các loại "mạnh" dựa trên nguồn dữ liệu đã nhập "yếu", sử dụng cơ chế cung cấp kiểu F # 3.0. Các kiểu được tạo ra phải có thể truy cập được từ các máy khách C# trong một môi trường chỉ có .Net 4.0 được cài đặt, nhưng không phải .Net 4.5. Nếu không thể tương thích .Net 4.0, chúng tôi không thể sử dụng các nhà cung cấp kiểu trong dự án ERP quy mô lớn hiện tại của chúng tôi.Làm thế nào để tạo C# -friendly, các loại tương thích .Net 4.0 sử dụng các nhà cung cấp loại F # 3.0

Cho đến nay, tôi đã thành công trong việc tạo MyGeneratedTypes.dll bằng cách làm theo tutorial trên msdn (phần "Cung cấp loại được tạo)", sử dụng ProvidedTypeDefinition từ "ProvidedTypes-0.2.fs", là một phần của mẫu F # 3.0 đóng gói. (Để nó hoạt động, tôi phải xóa dòng "File.Delete ..." từ phương thức "ProvidedTypeDefinition.ConvertToGenerated ...").

MyGeneratedTypes.dll có phiên bản thời gian chạy v4.0.30319, là OK (thời gian chạy là .Net 4.0). Tôi có thể thêm một tham chiếu đến MyGeneratedTypes.dll trong ứng dụng C#/.Net 4.0 và IntelliSense hiển thị các loại và thành viên như mong đợi. Tuy nhiên, khi tôi cố gắng biên dịch, trình biên dịch C# thất bại và tạo ra 'cảnh báo MSB3258: Tham chiếu chính "MyGeneratedTypes" không thể được giải quyết vì nó có sự phụ thuộc gián tiếp vào hội đồng .NET Framework "FSharp.Core, Version = 4.3.0.0 , Văn hóa = trung lập, PublicKeyToken = b03f5f7f11d50a3a "có phiên bản cao hơn" 4.3.0.0 "so với phiên bản" 4.0.0.0 "trong khung mục tiêu hiện tại. '

Một cái nhìn tại IL Spy xác nhận rằng MyGeneratedTypes.dll thực sự chứa tham chiếu đến FSharp.Core 4.3, eventhough tham chiếu này là hoàn toàn không cần thiết. Cho đến nay, tôi đã tìm thấy không có cách nào để ngăn chặn trình biên dịch F # đưa tham chiếu này vào assembly được tạo ra. (Trong số những thứ khác, tôi đã tạo ra một hội đồng .Net 4.0 thuần túy trong C# và chuyển nó cho hàm tạo của ProvidedTypeDefinition, nhưng điều này không có ảnh hưởng).

Không ai biết a) cách loại bỏ tham chiếu hoặc b) nếu đây chỉ là vấn đề của ứng cử viên phát hành F # 3.0, sẽ được giải quyết trong bản phát hành cuối cùng.

Sửa

Các cuộc trò chuyện với @ Brian đã dẫn đến việc làm theo giải pháp "một phần" cho vấn đề: Bạn thể biên soạn một "tinh khiết C#/Net 4,0" khách hàng tham khảo một thư viện với F # 3.0 các kiểu được tạo ra, nhưng chỉ bằng cách gọi trình biên dịch .NET 4.0 C# (csc) trực tiếp từ dòng lệnh. Nó không hoạt động khi biên dịch trong VS 2010 hoặc thông qua dòng lệnh MSBuild. Tôi nghi ngờ điều này là do hành vi sau:

  1. MyGeneratedTypes.dll được tạo trong VS 2012 với cơ chế nhà cung cấp loại F #.
  2. Trong quá trình tạo, tham chiếu đến FSharp.Core 4.3 được tự động chèn (ngay cả khi không cần), mà không chỉ định "SpecificVersion: true" trong siêu dữ liệu cho phụ thuộc.
  3. Máy khách C# trong VS 2010 trên hệ thống ". 4,5 miễn phí" tham chiếu MyGeneratedTypes.dll.
  4. Khi trình khách C# được biên soạn, MSBuild phát hiện ra tham chiếu gián tiếp tới FSharp.Core 4.3 bên trong MyGeneratedTypes.dll.
  5. Vì tham chiếu gián tiếp tồn tại với "SpecificVersion: false", MSBuild phát ra cảnh báo MSB3257 và từ chối chuyển tham chiếu trực tiếp /r:"MyGeneratedTypes.dll "tới trình biên dịch C# (csc). (Lưu ý: Cảnh báo MSBuild không thể bị chặn theo bất kỳ cách nào.)
  6. Trình biên dịch C# (csc) được gọi là MSBuild, không có /r:"MyGeneratedTypes.dll ".Do đó, nó không thể biên dịch và phát ra lỗi trình biên dịch CS0246: "Không thể tìm thấy loại tên hoặc không gian tên 'MyGeneratedTypes' (...)".

Theo tôi có thể nói, chúng tôi đang gặp vấn đề này trừ khi cơ chế nhà cung cấp loại F # được sửa đổi hoặc a) để loại trừ ref thành FSharp.Core 4.3 khi không cần thiết trong hội đồng được tạo, hoặc b) để bao gồm ref với siêu dữ liệu "SpecificVersion:true".

+2

Tôi không có câu trả lời, nhưng tôi tò mò - tại sao bạn muốn sử dụng nhà cung cấp loại F # nếu bạn định sử dụng thư viện từ C#? Bạn có dự định chuyển sang F # trong tương lai không? Bởi vì nếu không, sử dụng CodeDOM hoặc Roslyn có thể là cách dễ dàng hơn để giải quyết vấn đề. Tôi nghĩ rằng hầu hết các giá trị của các nhà cung cấp loại đến khi bạn tiêu thụ chúng từ F # ... –

+0

@Tomas Chúng tôi đang sử dụng F # như một ngôn ngữ bổ sung trong phần không giao diện người dùng của một giải pháp bao gồm phần lớn các dự án C#. Tôi hy vọng rằng các nhà cung cấp kiểu cung cấp một cách đơn giản để tạo ra một trình tạo kiểu CLI (bằng cách sử dụng _F # quotations_ và API được sắp xếp hợp lý của _ProvidedTypeDefinition_). Cho đến nay, tôi thích những gì tôi nhìn thấy, nhưng nó không biên dịch với C# (chưa?). Trong nhiều năm, chúng tôi đã sử dụng một máy phát điện tự tạo ra những tập tin mã nguồn C#, đó là một rắc rối để duy trì. Tôi sẽ xem xét CodeDom và Roslyn nếu nhà cung cấp loại không hoạt động - cảm ơn đề xuất. –

Trả lời

6

Chỉ cần thêm tham chiếu đến FSharp.Core 4.3.0.0 trong dự án C# (hoặc bỏ qua cảnh báo). Mặc dù quy ước đánh số kỳ lạ, FSharp.Core 4.3.0.0 không phụ thuộc vào bất kỳ thứ gì trong .Net 4.5, nó chỉ phụ thuộc vào .Net 4.0.

+0

Tôi đã thử điều này. Dù bằng cách nào, trình biên dịch C# đưa ra hai lỗi nói rằng nó không tìm thấy vùng tên và kiểu trong assembly được tạo ra, mặc dù cả hai đều có thể nhìn thấy hoàn toàn qua C# IntelliSense (Không có vấn đề gì với thời gian mã hóa C#, chỉ ở thời gian biên dịch C#). Thông điệp duy nhất khác từ trình biên dịch C# là cảnh báo "tham chiếu F # nội bộ", điều này vô hại theo câu trả lời của bạn. Trong IL Spy, hội đồng có vẻ bình thường ngoại trừ tham chiếu F #. Nếu tham chiếu F # bên trong không phải là nguyên nhân gốc rễ của vấn đề, tôi không biết điều gì khác có thể là ... –

+2

Ok, sẽ rất hữu ích khi chia sẻ các lỗi trình biên dịch thực tế mà bạn nhận được. Vì vậy, bạn đang nói ildasm/ilspy thấy rằng các loại công khai xuất hiện trong hội đồng F #, nhưng đối với một số lý do trình biên dịch C# không 'thấy' chúng, mặc dù lắp ráp là tham chiếu với một '/ r' trên csc.exe dòng lệnh? – Brian

+0

Vâng, đó là những gì tôi đang nói. Ứng dụng khách C# /. Net 4.0 hoạt động tốt trên Windows 8 nơi có .Net 4.5 tồn tại. Tuy nhiên, nó không hoạt động trên Windows 7 chỉ có .Net 4.0 tồn tại. Ở đây, trình biên dịch C# phát hành hai thông điệp: 1) 'lỗi CS0246: Không thể tìm thấy tên kiểu hoặc không gian tên' MyGeneratedTypes '(bạn đang thiếu một chỉ thị sử dụng hoặc tham chiếu assembly?)', Và 2) cảnh báo như đã đề cập trong câu hỏi. Điều kỳ lạ là trong VS 2010 trên Windows 7, C# IntelliSense nhận ra loại, và không có vấn đề nào được báo cáo bởi C# IDE hoặc ReSharper. Nó chỉ không biên dịch. –

Các vấn đề liên quan