2009-05-29 3 views
11

Giả sử tôi có một dự án "MyFramework" có một số mã, được sử dụng trên một vài giải pháp. Mỗi giải pháp đều có quản lý kiểm soát nguồn riêng (SVN).Thực hành tốt nhất để chia sẻ Visual Studio Project (assembly) giữa các giải pháp

MyFramework là sản phẩm nội bộ và không có lịch phát hành chính thức và cũng như vậy đối với các giải pháp.

Tôi không muốn xây dựng và sao chép các tệp DLL cho tất cả 12 dự án, tức là các nhà phát triển mới nên có thể thực hiện một số svn-checkout và bắt đầu làm việc.

Cách tốt nhất để chia sẻ MyFramework trên tất cả các giải pháp này là gì?

Trả lời

7

Vì bạn đề cập đến SVN, bạn có thể sử dụng externals để "nhập" dự án khuôn khổ vào bản sao làm việc của từng giải pháp sử dụng nó.Điều này sẽ dẫn đến một bố cục như thế này:

C:\Projects 
    MyFramework 
    MyFramework.csproj 
    <MyFramework files> 

    SolutionA 
    SolutionA.sln 
    ProjectA1 
     <ProjectA1 files> 
    MyFramework <-- this is a svn:externals definition to "import" MyFramework 
     MyFramework.csproj 
     <MyFramework files> 

Với giải pháp này, bạn có mã nguồn của MyFramework có sẵn trong mỗi giải pháp mà sử dụng nó. Ưu điểm là, bạn có thể thay đổi mã nguồn của MyFramework từ bên trong mỗi giải pháp này (mà không phải chuyển sang một dự án khác).

NHƯNG: đồng thời đây cũng là một bất lợi lớn, vì nó làm cho nó rất dễ dàng để phá vỡ MyFramwork cho một số giải pháp khi modifiying nó cho nhau.

Vì lý do này, gần đây tôi đã loại bỏ cách tiếp cận đó và hiện đang xử lý các dự án khung của chúng tôi như một giải pháp/sản phẩm hoàn toàn riêng biệt (với lịch phát hành riêng). Tất cả các giải pháp khác sau đó bao gồm một phiên bản cụ thể của các tệp nhị phân của các dự án khung.

Điều này đảm bảo rằng thay đổi được thực hiện cho thư viện khung không phá vỡ bất kỳ giải pháp nào đang sử dụng lại thư viện. Đối với mỗi giải pháp, bây giờ tôi có thể quyết định khi nào tôi muốn cập nhật lên phiên bản mới hơn của các thư viện khung công tác.

+0

Tôi thích cách tiếp cận này, tôi sẽ phải đọc thêm về các phần bên ngoài. Tôi giả sử bạn có thể thay đổi mọi thứ và cam kết với repo đúng khi bạn đã hoàn tất. Khung làm việc rất trẻ (gần đây chúng tôi nhận ra rằng chúng tôi đã viết cùng một mã trên toàn bộ địa điểm) để có thể thực hiện các thay đổi nhanh chóng cao trong danh sách ưu tiên. Đảm bảo rằng những thay đổi đó cũng không phá vỡ mọi thứ khác cũng quan trọng. –

4

Đó có vẻ là một thảm họa ... làm thế nào để bạn đối phó với các nhà phát triển hoàn tác/phá vỡ công việc của những người khác ...

Nếu tôi là bạn, tôi muốn đặt MyFrameWork trong một giải pháp hoàn toàn riêng biệt. Khi một nhà phát triển muốn phát triển một trong 12 dự án, anh ta mở giải pháp dự án đó trong một IDE & mở MyFrameWork trong một IDE riêng biệt.

Nếu bạn đặt tên cho MyFramework Assemby & GAC và tham chiếu nó trong các dự án khác của bạn, thì "Sao chép tệp DLL" sẽ không là vấn đề.

Bạn chỉ cần xây dựng MyFrameWork (và một sự kiện PostBuild có thể chạy GacUtil để đặt nó trong bộ đệm ẩn) và sau đó xây dựng dự án khác của bạn.

+0

đó chắc chắn là một xem xét, nhưng chúng tôi có CI trên tất cả các dự án vì vậy ít nhất chúng tôi sẽ sớm tìm thấy nó. Theo như GAC, tôi muốn tránh GAC nếu có thể. –

1

Tôi đồng ý với một áp phích khác - nghe có vẻ như rắc rối. Nhưng nếu bạn không thể làm điều đó "đúng cách" tôi có thể nghĩ ra hai cách khác để làm điều đó. Chúng tôi sử dụng một cái gì đó tương tự như số 1 dưới đây. (đối với ứng dụng gốc C++)

  1. một tập lệnh hoặc tập tin thực thi hoặc quá trình khác chạy và tạo phụ thuộc. (chỉ một lần) Điều này được xây dựng/thực hiện chỉ khi không có thay đổi trong repo. Bạn sẽ cần phải biết thẻ/chi nhánh/phiên bản nào sẽ nhận được. Bạn có thể sử dụng một tập tin bat như là một bước prebuild trong các tập tin dự án của bạn.

  2. Giữ các tệp nhị phân trong repo (không phải là ý tưởng hay). Ngay cả trong trường hợp này, các dự án phụ thuộc phải làm một việc và phải biết về phiên bản nào cần có.

Cuối cùng, những gì chúng tôi đã cố gắng làm cho dự án của chúng tôi bắt chước cách chúng tôi sử dụng và tham khảo thư viện của bên thứ ba.

Việc bạn có thể làm là tạo gói phát hành cho sự phụ thuộc thiết lập biến env đường dẫn cho chính nó. Tôi sẽ cho phép nhiều phiên bản của nó tồn tại trên máy và sau đó các liên kết dự án phụ thuộc/tham khảo các phiên bản cụ thể.

Something như

$(PROJ_A_ROOT) = c:\mystuff\libraryA 

$(PROJ_A_VER_X) = %PROJ_A_ROOT%\VER_X 

và sau đó tham khảo các phiên bản bạn muốn trong các giải pháp phụ thuộc hoặc bằng tên cụ thể, hoặc sử dụng var phiên bản env.

Không đẹp, nhưng nó hoạt động.

2

"Cách tốt nhất" sẽ tùy thuộc vào môi trường của bạn. Tôi đã làm việc trong một môi trường tích hợp liên tục dựa trên TFS, nơi xây dựng hàng đêm triển khai các tệp nhị phân cho một phần. Tất cả các dự án phụ thuộc đều được chia sẻ. Khi điều này diễn ra chậm, tôi đã xây dựng một số công cụ để cho phép các nhà phát triển có một bản sao cục bộ của các tệp nhị phân được chia sẻ, mà không cần thay đổi các tệp dự án.

2

Có hoạt động trong bất kỳ giải pháp nào trong số 12 giải pháp thường xuyên yêu cầu thay đổi mã "khung" không?

Nếu vậy khung của bạn có thể mới và vừa được tạo, vì vậy tôi sẽ chỉ đưa dự án khung vào trong tất cả các giải pháp. Sau khi tất cả, nếu công việc ra lệnh rằng bạn phải thay đổi mã khung, nó sẽ dễ dàng để làm như vậy.

Vì những thay đổi trong khung làm từ một giải pháp sẽ ảnh hưởng đến tất cả các giải pháp khác, sự cố sẽ xảy ra và bạn sẽ phải giải quyết chúng.

Một khi bạn hiếm khi phải thay đổi khung công tác khi bạn làm việc trong các giải pháp (đây nên là mục tiêu của bạn) thì tôi sẽ bao gồm tham chiếu đến dll khung thay thế và cập nhật dll trong mỗi giải pháp khi cần.

2

svn:externals sẽ xử lý điều này một cách độc đáo nếu bạn tuân theo một vài quy tắc.

Đầu tiên, sẽ an toàn hơn nếu bạn sử dụng các URI tương đối (bắt đầu bằng^ký tự) cho định nghĩa svn: externals và đặt các dự án trong cùng một kho lưu trữ nếu có thể. Bằng cách này, các định nghĩa sẽ vẫn hợp lệ ngay cả khi máy chủ lật đổ được chuyển đến một URL mới.

Thứ hai, đảm bảo bạn làm theo gợi ý sau đây từ sách SVN. Sử dụng PEG-revs trong svn của bạn: định nghĩa externals để tránh vỡ ngẫu nhiên và các thẻ không ổn định:

Bạn nên nghiêm túc xem xét sử dụng số sửa đổi rõ ràng trong tất cả các externals bạn các định nghĩa. Làm như vậy có nghĩa là bạn quyết định thời điểm để kéo xuống một ảnh chụp nhanh khác nhau của thông tin bên ngoài và chính xác ảnh chụp nào để kéo.Bên cạnh tránh sự ngạc nhiên của nhận thay đổi kho của bên thứ ba mà bạn có thể không có bất kỳ kiểm soát hơn, sử dụng số sửa đổi rõ ràng cũng có nghĩa là khi bạn Backdate bản sao làm việc của bạn để một phiên bản trước, externals bạn định nghĩa sẽ cũng trở lại theo cách mà họ nhìn vào đó phiên bản trước ...

+0

Các câu trả lời khác đề cập đến việc sử dụng svn: externals có thể dễ dàng phá vỡ các giải pháp khác. Tôi muốn chỉ ra (một lần nữa), rằng việc sử dụng các số sửa đổi rõ ràng có thể loại bỏ vấn đề này. Sử dụng một rev cụ thể sẽ dẫn đến kết quả tương tự như sao chép một nhị phân cụ thể vào giải pháp, cộng với bạn nhận được gỡ lỗi dễ dàng hơn và không sao chép các tập tin nhị phân xung quanh.Tôi có thể tưởng tượng bằng cách sử dụng rev hiện tại của MyFramework trên thân của tất cả các giải pháp và khi tôi tạo ra một RC cho một giải pháp tôi sẽ pin bên ngoài vào một rev cụ thể của MyFramework. – Tom

1

Một giải pháp khả năng mở rộng là để làm svn-external trên thư mục giải pháp để các dự án nhập khẩu của bạn xuất hiện song song với dự án khác của bạn S. Lý do cho điều này được đưa ra dưới đây.

Sử dụng thư mục con riêng cho các dự án "được nhập", ví dụ: externals, qua svn-external có vẻ như là một ý tưởng hay cho đến khi bạn có các phụ thuộc không tầm thường giữa các dự án. Ví dụ, dự án Giả sử một phụ thuộc vào dự án trên dự án B, và dự án B của dự án C. Nếu bạn sau đó có một giải pháp S với dự án A, bạn sẽ kết thúc với cấu trúc thư mục sau:

# BAD SOLUTION # 
S 
+---S.sln 
+---A 
| \---A.csproj 
\---externals 
    +---B  <--- A's dependency 
    | \---B.csproj 
    \---externals 
     \---C  <--- B's dependency 
      \---C.csproj 

Sử dụng kỹ thuật này, bạn thậm chí có thể có nhiều bản sao của một dự án duy nhất trong cây của mình. Điều này rõ ràng không phải là những gì bạn muốn.

Hơn nữa, nếu dự án của bạn sử dụng phụ thuộc NuGet, chúng thường được tải trong thư mục cấp cao nhất packages. Điều này có nghĩa là Tham chiếu NuGet của các dự án trong thư mục con externals sẽ bị hỏng.

Ngoài ra, nếu bạn sử dụng Git ngoài SVN, cách thay đổi theo dõi được đề xuất là có kho lưu trữ Git riêng cho từng dự án và sau đó là kho lưu trữ Git riêng cho giải pháp sử dụng git submodule cho các dự án bên trong. Nếu một mô-đun con Git không phải là một thư mục con ngay lập tức của mô-đun cha, thì Lệnh submodule Git sẽ tạo một bản sao là một thư mục con ngay lập tức. Một lợi ích khác của việc có tất cả các dự án trên cùng một lớp là bạn có thể tạo "siêu giải pháp", chứa các dự án từ tất cả các giải pháp của bạn (được theo dõi qua Git hoặc svn-external), cho phép bạn để kiểm tra với một giải pháp xây dựng lại duy nhất mà bất kỳ thay đổi nào bạn đã thực hiện cho một dự án duy nhất đều phù hợp với tất cả các dự án khác.

# GOOD SOLUTION # 
S 
+---S.sln 
+---A 
| \---A.csproj 
+---B  <--- A's dependency 
| \---B.csproj 
\---C  <--- B's dependency 
    \---C.csproj