2012-06-14 39 views
9

Làm thế nào có thể một assembly .NET duy nhất, nhắm mục tiêu 2.0, 3.0, 3.5, 4.0, và 4.5 đồng thời, phương pháp hỗ trợ mở rộng cho cả C# và người tiêu dùng VB.NET?thoát Catch-22 với phần mở rộng thuộc tính trong .NET 2.0

Đề nghị giữa các ý kiến ​​để thêm video này:

namespace System.Runtime.CompilerServices 
{ 
    public sealed class ExtensionAttribute : Attribute { } 
} 

Cách tiếp cận này là đề xuất bởi more hơn one Microsoft employee và thậm chí còn đặc trưng trong MSDN magazine. Đó là widely được ca ngợi bởi many bloggers vì có 'không ảnh hưởng xấu'.

Oh, ngoại trừ nó sẽ gây ra một lỗi biên dịch từ một nhắm mục tiêu NET 3.5 hoặc cao hơn dự án VB.NET.

Các tác giả của Microsoft.Core.Scripting.dll figured it out, và thay đổi 'công cộng' thành 'nội'.

namespace System.Runtime.CompilerServices 
{ 
    internal sealed class ExtensionAttribute : Attribute { } 
} 

Điều này dường như giải quyết vấn đề tương thích VB.

Vì vậy, tôi tin tưởng sử dụng cách tiếp cận này cho phiên bản mới nhất (3.2.1) của widely-used ImageResizing.Net library.

Nhưng sau đó, chúng tôi bắt đầu nhận được lỗi trình biên dịch này (original report), nhiều hoặc ít ngẫu nhiên, đối với một số người dùng nhắm mục tiêu .NET 3.5+.

Error 5 Missing compiler required member 
'System.Runtime.CompilerServices.ExtensionAttribute..ctor' 

Vì MSBuild/VisualStudio biên dịch dường như không bận tâm để nhìn vào quy tắc Phạm vi khi giải quyết đặt tên xung đột, và thứ tự của tài liệu tham khảo lắp ráp đóng một vai trò không-khá-docuemented, tôi không hoàn toàn hiểu tại sao và khi điều này xảy ra.

Có một few hacky workarounds, như thay đổi không gian tên lắp ráp, tạo lại tệp dự án, xóa/readding System.Core và không sử dụng phiên bản đích của khuôn khổ .NET. Thật không may, không có cách giải quyết nào là 100% (trừ bí danh, nhưng đó là một nỗi đau không thể chấp nhận được).

Làm thế nào tôi có thể sửa lỗi này trong khi

  1. Duy trì hỗ trợ cho việc sử dụng phương pháp khuyến nông trong việc lắp ráp,
  2. Duy trì hỗ trợ cho .NET 2.0/3.0
  3. Không đòi hỏi nhiều hội cho mỗi phiên bản .NET framework .

Hoặc, có một hotfix để làm cho trình biên dịch chú ý đến các quy tắc phạm vi không?

câu hỏi liên quan về SO mà không trả lời câu hỏi này

+0

Ugh. Tiền thưởng của bạn bị thiếu số không. Tốt nhất để thực hiện việc này với Hỗ trợ của Microsoft, mặc dù họ có khả năng loại bỏ nó bằng 'không được hỗ trợ'. –

Trả lời

1

Chúng tôi đã gặp sự cố tương tự với IronPython. http://devhawk.net/2008/10/21/the-fifth-assembly/

Chúng tôi đã chuyển phiên bản tùy chỉnh của ExtensionAttribute thành hội đồng của riêng mình. Bằng cách đó, khách hàng có thể lựa chọn giữa việc tham chiếu đến AssemblyAttribute tùy chỉnh của chúng tôi hoặc System.Core - nhưng không bao giờ cả hai!

Điều phức tạp khác là bạn phải luôn luôn triển khai lắp ráp ExtensionAttribute - ngay cả khi bạn không tham chiếu nó trong dự án của bạn. Các hội đồng dự án của bạn để lộ các phương thức mở rộng sẽ có một assemblyref cho assembly AssemblyAttribute tùy chỉnh đó, vì vậy CLR sẽ khó chịu nếu nó không thể được tìm thấy.

Với yêu cầu khó khăn về hỗ trợ .NET 2.0, tôi cho rằng đặt cược tốt nhất sẽ đơn giản là không sử dụng các phương pháp mở rộng. Tôi không quen thuộc với dự án ImageResizer, nhưng có vẻ như đây là một thay đổi gần đây trong ImageResizer. Làm cách nào để thay đổi các phương pháp mở rộng thành các phương pháp tĩnh truyền thống? Chúng tôi thực sự nghĩ về điều đó cho IronPython/DLR, nhưng nó không khả thi (Chúng tôi đã hợp nhất với LINQ tại thời điểm đó và LINQ đã sử dụng nhiều phương pháp mở rộng cho toàn bộ sự tồn tại của nó).

+0

Cảm ơn bạn đã cập nhật bài viết bằng một liên kết! Tôi nghĩ Newtonsoft.Json chạy vào cùng một cơn ác mộng mà chúng tôi đã làm ... Quá nhiều blog ở đó nói rằng không có hậu quả, và khi tôi đọc cùng một thực tế không thể tranh cãi trên nửa tá blog, tôi cho rằng đó là sự thật! –

+0

Chỉ cần ý tưởng, chúng ta có thể đi lại với kiểu chuyển tiếp bằng cách nào đó không? –

+0

Chúng tôi vẫn cần nhiều phiên bản của hội đồng ... –

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