2010-07-03 4 views
14

Điều này nghe có vẻ giống như một câu hỏi ngu ngốc, nhưng tôi sẽ cung cấp cho nó một shot anyway.Có thể bật phụ thuộc vòng tròn trong Visual Studio ở cấp độ lắp ráp không? Liệu các hội đồng phụ thuộc lẫn nhau thậm chí có thể có được không?

Vì vậy, trong Visual Studio, bạn không thể có hai dự án X và Y như rằng X tham chiếu Y và Y tài liệu tham khảo X.

Nói chung, tôi hoàn toàn có thể hiểu có một phụ thuộc vòng tròn có thể có vấn đề, cho nhiều lý do.

Nhưng thực sự không phải là có thể để biên dịch hai dự án phụ thuộc lẫn nhau theo cách này không? Dường như với tôi rằng nó phải có thể, vì (trong tâm trí của tôi - có lẽ tôi là hoàn toàn off-base về điều này) có hai hội đồng phụ thuộc lẫn nhau thực sự không phải là vì vậy khác với hai lớp phụ thuộc lẫn nhau - trường hợp hợp pháp và có thể được biên dịch.

Nó sẽ hợp lý với tôi nếu bạn nói, "hai hội đồng không thể phụ thuộc vào nhau vì trình biên dịch không thể biên dịch một trước khi khác"; ngoại trừ việc có vẻ như bạn có thể làm cho cùng một đối số cho hai lớp trong cùng một assembly, và rõ ràng trình biên dịch có thể xử lý kịch bản này tốt.

Về cơ bản lý do tôi yêu cầu không phải là tôi có một số mong muốn tuyệt vọng để làm điều này mà tôi biết nói chung là không được thông báo. Cụ thể là tôi tự hỏi vì sẽ tốt hơn nếu tôi có hai dự án - MyProjectCS và MyProjectVB - tồn tại về cơ bản là hai phần phụ thuộc lẫn nhau của một đơn vị và chỉ tách biệt vì một số phần nhất định được viết bằng C# và các phần khác được viết bằng VB.NET.

Vì vậy, câu hỏi của tôi là (yikes, ba lần):

  1. Có thể cho phép hành vi này (trong Visual Studio, hay ở nơi khác, cho rằng vấn đề)?
  2. Nếu không thể trong bất kỳ IDE nào, có ít nhất về mặt lý thuyết có thể, hoặc có thể phụ thuộc lẫn nhau các cụm không thể tồn tại?
  3. Nếu nó thậm chí không lý thuyết có thể, tại sao không? Nói cách khác, làm thế nào là hội đồng phụ thuộc lẫn nhau khác nhau từ mã phụ thuộc lẫn nhau trong một hội đồng duy nhất?
+7

Điều này xảy ra với tôi tất cả các thời gian ... dự án Egg của tôi ném 'Chicken.dll không tìm thấy ...' trong khi dự án gà của tôi ném một lỗi tương tự. Ho-hum. –

+2

.NET framework sử dụng các assembly phụ thuộc lẫn nhau. Ai đó đã phát hiện ra một lúc trước sau khi tháo gỡ các hội đồng .NET và đặt ra câu hỏi đó trên SO (không thể tìm thấy liên kết). – Alex

+0

@ Alex yeah Tôi thấy rằng một lần. Nó nhìn tôi như thể nó đã làm nó qua sự phản chiếu. – Joshua

Trả lời

11

Tôi không biết cách thực hiện trong IDE; tuy nhiên nó có thể xây dựng thông qua một quá trình xây dựng compilicated.

Bạn sẽ cần:

  1. hội Một
  2. hội B
  3. Stub hội B

nơi Stub hội B chứa các lớp công cộng và phương pháp công cộng của hội B và cùng AssemblyInfo. * Và tham chiếu cùng khóa công khai.

trật tự

tích xây dựng:

  1. Compile Stub hội B
  2. Sao chép Stub hội B vào thư mục đầu ra của hội B
  3. xây dựng lắp ráp Một
  4. lắp ráp xây dựng B

Thông báo rằng bạn không thể có tham chiếu vòng lặp trực tiếp của các kiểu trong chữ ký phương thức; tuy nhiên bạn có thể có các vòng lặp hiệu quả bằng cách truyền qua đối tượng.

LƯU Ý:

ILASM có thể biên dịch đúng cụm lẫn nhau đệ quy như bằng cách nào đó nó có thể giải quyết các loại mà không hề tồn tại thời gian biên dịch.

THÊM:

các aspnet_compiler dường như để có thể pha trộn ngôn ngữ khác nhau trong cùng một dự án (người hiểu biết như thế nào).

+3

Bạn có thể có vòng trong các kiểu chữ ký bằng cách sử dụng quá trình xây dựng phức tạp hơn: đầu tiên xác định tất cả các lớp và biên dịch, sau đó thiết lập hệ thống phân cấp thừa kế (sử dụng các bước từ bước trước) và thêm tất cả các phương thức không ghi đè (nhưng không có cơ quan), và trong một vượt qua thứ ba cuối cùng làm một trình biên dịch bình thường (bây giờ cuối cùng bao gồm các cơ quan phương pháp). Nếu bạn thực sự muốn làm điều này, #if sẽ là người bạn thân nhất của bạn. – Daniel

+0

wow Daniel Tôi chưa bao giờ nghĩ về điều đó. – Joshua

2

Tôi không biết nó sẽ hoạt động như thế nào trong VB, nhưng về mặt lý thuyết thì có thể sử dụng một loại trình giữ chỗ nào đó. khác, và sau đó biên dịch lại đầu tiên.

Đó là cách, ví dụ, độ phân giải phụ thuộc vòng tròn hoạt động khi biên dịch chương trình yêu cầu lẫn nhau.

--Thường thường được thực hiện bằng cách tắt các tính năng chưa tồn tại

+3

FYI, trong bản C và C++, chúng tôi thực hiện điều này nhờ vào các tệp tiêu đề. – Joshua

+0

@Joshua, điều này hoạt động nếu cả hai thứ phụ thuộc lẫn nhau được biên dịch và liên kết cùng một lúc. Mô tả của câu trả lời về "tắt các tính năng chưa tồn tại" thường được sử dụng để phá vỡ các chu kỳ ở cấp gói với sự trợ giúp của trình quản lý gói. – binki

+0

Trình quản lý gói của tôi có thể xử lý các phụ thuộc theo chu kỳ. – Joshua

6

Mặc dù hội đồng mscorlib.dll và System.dll đều phụ thuộc lẫn nhau, tôi khuyên không bao giờ nên có 2 hội đồng phụ thuộc lẫn nhau.

Liên quan đến các chu kỳ phụ thuộc giữa các vị trí như không gian tên, tôi khuyên bạn nên sử dụng NDepend để phát hiện và tránh dependency cycles.

alt text

Trích từ bài báo (tôi đã viết): Control component dependencies to gain clean architecture

chu kỳ phụ thuộc giữa các thành phần dẫn đến những gì thường được gọi là spaghetti mã hoặc mã rối. Nếu thành phần A phụ thuộc vào B phụ thuộc vào C phụ thuộc vào A, thì thành phần A không thể được phát triển và thử nghiệm độc lập với B và C. A, B và C tạo thành một đơn vị không thể tách rời, một loại siêu thành phần. Siêu thành phần này có chi phí cao hơn tổng chi phí trên A, B và C do sự không cân đối của hiện tượng quy mô (được ghi lại trong Ước tính phần mềm: Làm sáng tỏ nghệ thuật đen của Steve McConnell). Về cơ bản, điều này cho thấy chi phí phát triển một đoạn mã không thể tách rời tăng theo cấp số nhân. Điều này cho thấy rằng việc phát triển và duy trì 1.000 LOC (Lines of Code) có thể sẽ tốn gấp ba hoặc bốn lần so với việc phát triển và duy trì 500 LOC, trừ khi nó có thể được chia thành hai khối độc lập 500 LOC mỗi cái. Do đó so sánh với spaghetti mô tả mã rối mà không thể được duy trì. Để hợp lý hóa kiến ​​trúc, người ta phải đảm bảo rằng không có chu kỳ phụ thuộc giữa các thành phần, mà còn kiểm tra xem kích thước của mỗi thành phần có thể chấp nhận được (500 đến 1000 LOC) hay không.

+2

Một phản hồi rất chu đáo và mang tính thông tin. Tuy nhiên, tôi chỉ muốn chỉ ra rằng tôi chủ yếu đặt câu hỏi này từ góc độ mong muốn có thể viết một thành phần trong sự kết hợp của C# và VB.NET. Vì vậy, mặc dù tôi nhận được những gì bạn có nghĩa là "siêu thành phần", tôi cảm thấy rằng nó không hoàn toàn phù hợp với những gì tôi đã sau. Với tôi một "siêu thành phần" sẽ là sự kết hợp của nhiều thành phần phụ thuộc lẫn nhau; một "hỗn hợp thành phần", như tôi sẽ gọi nó, mặt khác, sẽ là sự phân hủy (theo ngôn ngữ) của một thành phần * đơn * thành phụ thuộc lẫn nhau * các phần *. Điều đó có ý nghĩa? –

+0

Bạn nên chọn VB.NET hoặc C# và di chuyển ngôn ngữ khác sang ngôn ngữ được chọn (với sự trợ giúp của .NET Reflector chẳng hạn, có thể chuyển đổi mã C# thành VB.NET hoặc ngược lại). Không thể có lý do chính đáng để duy trì 2 ngôn ngữ để mã hóa cùng một assembly. –

1

Nếu bạn xây dựng bằng cách sử dụng các công cụ dòng lệnh, bạn có thể có một hội đồng có chứa nhiều mô-đun. Mỗi mô-đun có thể được biên dịch với một trình biên dịch khác. Mô-đun có thể có phụ thuộc vòng tròn giữa chúng.

Tuy nhiên, tôi không mong đợi phòng thu trực quan bao giờ hết khả năng này.


Ngoài ra còn có mẹo bạn có thể làm điều đó sẽ yêu cầu trình liên kết chuyển hướng yêu cầu cho loại từ một hội đồng này sang nhóm khác. Microsoft sử dụng chúng sau đó họ di chuyển các loại trong khuôn khổ .net. Đây chỉ là giá trị nếu bạn không thể thu hút tất cả người gọi của mình để biên dịch lại mã đó.

0

Có thể có phụ thuộc vòng tròn trong Visual Studio nếu bạn sử dụng trình biên dịch có điều kiện. Hầu hết thời gian sẽ là tốt nhất để loại bỏ tham chiếu vòng tròn để bắt đầu, nhưng nếu bạn có lý do chính đáng để giữ chúng, this solution có thể được sử dụng như một cách giải quyết để xây dựng nó.