2011-01-22 32 views
9

Giả sử chúng ta có class X trong phiên bản 1 của lắp ráp A.dll:C# giao diện vỡ, ABI

class X { 
    SomeType Property { set; get; } 
} 

và sau đó trong phiên bản 2 của lắp ráp A.dll:

class X { 
    SomeType Property { set; get; } 
    SomeType OtherProperty { set; get; } 
} 

Bây giờ giả sử chúng ta có một lắp ráp thứ hai B.dll tải A.dll và sử dụng X. Việc bổ sung tài sản OtherProperty có vi phạm ABI không? Sẽ B.dll không sử dụng A.dll/X? Nếu không, thứ tự của các tờ khai có khác biệt gì không? Nếu các thuộc tính đã được ảo, nó có tạo nên sự khác biệt nào không?

Tôi đoán tôi thực sự hỏi: các quy tắc ABI chung là gì? Tôi biết thay đổi giao diện sau khi chúng đã được xuất bản là một điều xấu, nhưng tôi thực sự muốn có thể thêm các thuộc tính trong một số trường hợp, mà không thêm các lớp con.

+1

Xem: Hướng dẫn rõ ràng về các thay đổi phá vỡ API trong .NET http: // stackoverflow.com/questions/1456785/a-definite-guide-to-api-breaking-changes-in-net – Ani

+0

Bạn tải các tệp DLL như thế nào? –

+0

@Mark: Tôi có các khách hàng của bên thứ ba đề cập đến một số hội đồng của tôi. Tôi có một vài lớp mà tôi muốn mở rộng với một vài thuộc tính. Tôi muốn làm như vậy mà không yêu cầu các bên thứ ba biên dịch lại các hội đồng của họ. Tôi có thể yêu cầu họ một cách độc đáo, nhưng tôi không muốn. Nó chỉ cho biết thêm thời gian quay vòng ... –

Trả lời

6

Việc thêm thuộc tính sẽ ổn.

Một trường hợp sẽ xảy ra là nếu bạn ví dụ thêm thứ gì đó vào giữa một enum được đánh số tự động. Ví dụ nếu bạn có mã này trong thư viện của bạn:

enum Foo 
{ 
    Bar, 
    Qux 
} 

và bạn thay đổi nó như thế này:

enum Foo 
{ 
    Bar, 
    Baz, 
    Qux 
} 

Sau đó, bạn cũng sẽ cần phải biên dịch lại bất kỳ mã như thế này:

if (foo == Foo.Qux) 
{ 
    // ... 
} 
+0

Giả sử tôi có một phương thức trả về một lớp cụ thể X. Nó có thể phá vỡ ABI nếu tôi trả về một giao diện tái cấu trúc IX không? Tôi cho rằng điều đó sẽ xảy ra, bởi vì IX không có mặt trong phiên bản đầu tiên của hội đồng. –

+0

@ Jörgen Sigvardsson: Nó * sẽ * OK trong hầu hết các trường hợp, nhưng có trường hợp góc mà nó có thể không hoạt động. Ví dụ nếu họ đang sử dụng sự phản chiếu để kiểm tra lớp thì họ sẽ có thể thấy bất kỳ thay đổi nào đối với ABI và theo lý thuyết nó có thể phá vỡ mã của họ. –

+0

@MarkByers Bạn có thể cung cấp một số tham chiếu về câu trả lời của bạn ở trên không? – erick2red

2

Nó sẽ không phá vỡ khả năng tương thích nếu chỉ được sử dụng bởi lắp ráp B. Nhưng nó sẽ phá vỡ nếu assembly B định nghĩa một lớp thực hiện giao diện, bởi vì lớp đó không thực hiện thuộc tính vừa mới được giới thiệu.

10

Trình biên dịch JIT sẽ giải quyết rất nhiều vấn đề này, cũng là nguồn gốc của thông báo lỗi nếu thay đổi bị phá vỡ.

Tuy nhiên, bạn đang chơi một trò chơi rất nguy hiểm có tên là DLL Hell. Vấn đề không phải là họ không biên dịch lại mã của họ, đó là khi họ làm. Họ sẽ, cuối cùng. Nếu sau đó có một sai lầm tinh tế, ai đó chạy một phiên bản cũ của trình cài đặt của bạn, sao chép các tập tin sai, etcetera sau đó tất cả các địa ngục vỡ lỏng. Mã sẽ không chạy và họ sẽ có công việc không thể thực hiện để tìm hiểu lý do. Điều này sẽ xảy ra lâu sau khi bạn thực hiện thay đổi, bạn sẽ không có bất kỳ cách nào để đoán điều gì đã xảy ra hoặc không thể giúp họ.

Đừng làm rối tung điều này, tăng [AssemblyFileVersion] và [AssemblyVersion]. Có, họ sẽ phải biên dịch lại khi bạn thay đổi thứ hai. Hoặc sử dụng <bindingRedirect>, điều này cũng tốt, bây giờ có một bản ghi có thể theo dõi được.

Btw: điều này cũng xảy ra trong Khuôn khổ .NET. WaitHandle.WaitOne (int) đã được thêm vào trong một gói dịch vụ nhưng không có thay đổi [AssemblyVersion]. Các lập trình viên nhắm mục tiêu .NET 2.0 nhưng mã của họ sẽ không chạy khi máy mục tiêu đã cài đặt bản gốc 2.0. Rất gây đau đớn.

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