2011-09-26 25 views
23

Kể từ phiên bản 3.0, .NET cài đặt một loạt các "hội đồng tham chiếu" khác nhau trong C: \ Program Files \ Reference Assemblies \ Microsoft ...., để hỗ trợ các cấu hình khác nhau (nói hồ sơ khách hàng .NET 3.5, hồ sơ Silverlight). Mỗi trong số đó là một assembly .NET thích hợp chỉ chứa siêu dữ liệu - không có mã IL - và mỗi assembly được đánh dấu bằng ReferenceAssemblyAttribute. Siêu dữ liệu bị hạn chế đối với các loại và thành viên có sẵn trong hồ sơ hiện hành - đó là cách intellisense hiển thị tập hợp các loại và thành viên bị hạn chế. Các hội đồng tham chiếu không được sử dụng trong thời gian chạy.Tôi làm cách nào để tạo và sử dụng .NET Reference-only 'Reference Assembly'?

Tôi đã học được một chút về nó từ this blog post.

Tôi muốn tạo và sử dụng một bộ tham chiếu như vậy cho thư viện của mình.

  1. Làm cách nào để tạo một hội đồng chỉ siêu dữ liệu - có một số cờ trình biên dịch hoặc bộ xử lý sau ildasm không?
  2. Có các thuộc tính kiểm soát loại được xuất sang 'cấu hình' khác nhau không?
  3. Độ phân giải lắp ráp tham chiếu trong thời gian chạy như thế nào - nếu tôi có bộ tham chiếu trong thư mục ứng dụng thay vì cụm từ 'thực', và không phải trong GAC, sẽ khảo sát tiếp tục và sự kiện AssemblyResolve của tôi có thể cung cấp lắp ráp thực tế tại thời gian chạy?

Bất kỳ ý tưởng hay gợi ý nào để tôi có thể tìm hiểu thêm về điều này sẽ được đánh giá cao.

Cập nhật: Nhìn xung quanh một chút, tôi thấy hội đồng tham chiếu .NET 3.0 'dường như có một số mã và Reference Assembly attribute chỉ được thêm trong .NET 4.0. Vì vậy, hành vi có thể đã thay đổi một chút với thời gian chạy mới.

Tại sao? Đối với thư viện bổ trợ Excel-DNA (http://exceldna.codeplex.com) của tôi, tôi tạo thêm một tệp .xll bổ trợ bằng cách đóng gói các assembly được tham chiếu vào tệp .xll dưới dạng tài nguyên. Các assembly được đóng gói bao gồm mã bổ trợ của người dùng, cũng như thư viện quản lý Excel-DNA (có thể được tham chiếu bởi assembly của người dùng).

Nghe có vẻ khá phức tạp, nhưng hoạt động tuyệt vời phần lớn thời gian - bổ trợ là một tệp nhỏ duy nhất, do đó không cài đặt các sự cố phân phối. Tôi gặp phải các vấn đề (không phải bất ngờ) vì các phiên bản khác nhau - nếu có một phiên bản cũ của thư viện được quản lý Excel-DNA dưới dạng tệp, thời gian chạy sẽ tải thay vì gói được đóng gói (tôi không bao giờ có cơ hội can thiệp vào tải).

Tôi hy vọng sẽ thực hiện một phiên bản tham chiếu cho phần quản lý Excel-DNA của mình mà người dùng có thể trỏ đến khi biên dịch bổ trợ của họ. Nhưng nếu họ nhầm lẫn có một phiên bản của hội đồng này tại thời gian chạy, thời gian chạy sẽ không tải nó, và cho tôi một cơ hội để tải lắp ráp thực sự từ các nguồn lực.

+1

Tại sao bạn muốn làm điều đó? – svick

Trả lời

9

Để tạo một hội đồng tham chiếu, bạn sẽ thêm dòng này vào tập tin AssemblyInfo.cs của bạn:

[assembly: ReferenceAssembly] 

Để tải khác, bạn có thể tham khảo chúng như bình thường từ tài liệu tham khảo dự án VisualStudio của bạn, hoặc tự động khi chạy sử dụng:

Assembly.ReflectionOnlyLoad()

hoặc

Assembly.ReflectionOnlyLoadFrom()


Nếu bạn đã thêm một tham chiếu đến một siêu dữ liệu/tài liệu tham khảo lắp ráp sử dụng VisualStudio, sau đó IntelliSense và xây dựng dự án của bạn sẽ chỉ làm việc tốt, tuy nhiên nếu bạn cố gắng để thực hiện ứng dụng của bạn chống lại một, bạn sẽ nhận được một lỗi:

System.BadImageFormatException: Cannot load a reference assembly for execution.

Vì vậy, kỳ vọng là lúc chạy bạn sẽ thay thế trong một hội đồng thực có cùng chữ ký siêu dữ liệu.

Nếu bạn đã nạp một cụm động với Assembly.ReflectionOnlyLoad() thì bạn chỉ có thể thực hiện tất cả các hoạt động phản chiếu đối với nó (đọc các loại, phương pháp, thuộc tính, thuộc tính, v.v ... nhưng không thể gọi động bất kỳ).


Tôi rất tò mò về trường hợp sử dụng của bạn là gì để tạo lắp ráp chỉ siêu dữ liệu. Tôi chưa bao giờ phải làm điều đó trước đây, và rất muốn biết nếu bạn đã tìm thấy một số sử dụng thú vị cho họ ...

+2

tạo thành ** ví dụ giả mạo **: bạn có thể tạo hình ảnh gốc của một hội đồng .NET bằng cách sử dụng ví dụ: Mono mkbundle.exe. Bây giờ bạn vẫn có thể muốn cho phép các plugin dll truy cập vào giao diện công cộng của assembly ban đầu. Tôi chắc chắn bạn có thể làm cho nó hoạt động theo cách này. Nếu bất cứ điều gì nó sẽ dẫn đến _really_ obfuscated và _large_ assemblies :) – sehe

+0

Việc thêm thuộc tính ReferenceAssembly không thay đổi đầu ra thành một assembly siêu dữ liệu giống như các tham chiếu .NET 4. Tôi đang cố gắng tìm hiểu xem chúng được xây dựng như thế nào. Tôi sẽ phải thử, nhưng sau khi xử lý BadImageFormatException, bạn có nghĩ rằng độ phân giải lắp ráp sẽ gọi trình xử lý AssemblyResolve của tôi không? (Tôi sẽ thêm chi tiết về trường hợp sử dụng của tôi vào câu hỏi.) – Govert

+0

Tôi đã thêm một số thông tin về lý do tôi quan tâm. @sehe không xa nhãn hiệu! Những cụm máy đóng gói này thực sự nhỏ, khi tôi nén chúng trước khi đóng gói, và các cụm CLI nén khá độc đáo. Kết quả là obfuscated chỉ trong ý nghĩa 'tối nghĩa' - các hội đồng NET không phải là trong khuôn mặt của bạn, vì vậy bạn phải làm một chút công việc trước khi chỉ cho họ tại ILSpy. Nhưng một obfuscator của loại đó sẽ là một trường hợp sử dụng tốt. – Govert

2

Có, đây là phiên bản mới dành cho .NET 4.0. Tôi khá chắc chắn điều này đã được thực hiện để tránh các vấn đề khó chịu versioning trong gói dịch vụ .NET 2.0. Ví dụ tốt nhất là quá tải WaitHandle.WaitOne (int), được thêm vào và được ghi lại trong SP2. Một quá tải phổ biến bởi vì nó tránh phải đoán giá trị thích hợp cho * exitContext "trong quá tải WaitOne (int, bool) Vấn đề là, các chương trình bom khi nó chạy trên một phiên bản 2.0 cũ hơn SP2. Việc phân lập các hội đồng tham chiếu đảm bảo rằng điều này không thể xảy ra lần nữa

I nghĩ rằng các assembly được tạo ra bằng cách bắt đầu từ một bản sao của các assembly đã biên dịch (như đã được thực hiện trong các phiên bản trước) và chạy chúng Công cụ đó tuy nhiên không có sẵn cho chúng ta, không có gì trong công cụ bin/netfx 4.0 Windows 7.1 SDK thư mục con có thể làm điều này. Không chính xác một công cụ được sử dụng thường xuyên vì vậy nó có lẽ không chất lượng sản xuất :)

+0

Ah! Tôi nghĩ rằng đó là công cụ mà tôi đang tìm kiếm ... – Govert

+1

Hans, tôi tin rằng công cụ đó thực sự được sử dụng thường xuyên hơn bạn nghĩ. Meta-data chỉ assembly cũng được sử dụng bootstrapping Core .Net Framework hội đồng, như được giải thích trong [câu trả lời này] (http://stackoverflow.com/questions/1316518/z/1316587) cho một câu hỏi về cách họ biên dịch. Net Hội đồng khung. Tất nhiên, có những thay đổi khác được thực hiện thông qua các công cụ đặc biệt cho các assembly đó, giống như các kiểu primitatives có tham chiếu tới thành phần 'm_value' được thay thế bằng tham chiếu đến' this'. –

+0

Cảm ơn Kevin về con trỏ đến câu hỏi khác. Vì vậy, các hội đồng tham chiếu đó là các cụm chỉ siêu dữ liệu 'bị mất nước'. – Govert

1

Bạn có thể gặp may mắn với Thư viện Cecil (từ Mono); Tôi nghĩ rằng việc thực hiện cho phép chức năng ILMerge, nó chỉ có thể viết siêu dữ liệu chỉ hội đồng.

Tôi đã quét cơ sở mã (tài liệu là thưa thớt), nhưng đã không tìm thấy bất kỳ manh mối rõ ràng chưa ...

YYMV

3

Nếu bạn vẫn còn quan tâm đến khả năng này, tôi đã thực hiện một ngã ba của dự án il-repack dựa trên Mono.Cecil chấp nhận một đối số dòng lệnh "/ meta" để tạo ra một tập hợp siêu dữ liệu chỉ cho các loại công cộng và được bảo vệ.

https://github.com/KarimLUCCIN/il-repack/tree/xna

(Tôi đã thử nó trên XNA Framework đầy đủ và làm việc của nó afaik ...)

+0

Cảm ơn bạn (cũng đã đăng bài trở lại đây)! Vẫn quan tâm - Tôi sẽ có một cái nhìn khi tôi có cơ hội. – Govert

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