Visual Studio (2008)의 대규모 솔루션에 대한 모범 사례 [닫기]


87

약 100 개 이상의 프로젝트가 포함 된 솔루션이 있습니다. 대부분은 C #입니다. 당연히 개봉하고 구축하는 데 시간이 오래 걸리므로 그런 짐승에 대한 모범 사례를 찾고 있습니다. 답변을 얻고 자하는 질문에는 다음과 같은 것들이 있습니다.

  • 프로젝트 간의 참조를 가장 잘 처리하는 방법
    • "로컬 복사"가 켜져 있거나 꺼져 있어야합니까?
  • 모든 프로젝트가 자체 폴더에 빌드되어야하는지 아니면 모두 동일한 출력 폴더에 빌드되어야합니까 (모두 동일한 애플리케이션의 일부 임)

  • 솔루션 폴더가 물건을 정리하는 좋은 방법입니까?

솔루션을 여러 개의 작은 솔루션으로 분할하는 것이 옵션이라는 것을 알고 있지만 자체 리팩토링 및 구축 문제가 있으므로 별도의 스레드에 대해 저장할 수 있습니다. :-)


2
단일 솔루션에 100 개 이상의 프로젝트가 필요한 이유를 물어봐도 될까요? 그들은 각자 자신의 어셈블리를 만들고 있습니까?
Neil N

1
예, 그렇습니다. 각각은 논리적으로 분리 된 기능을 나타냅니다.
Eyvind

2
@Eyvind-그게 어떤 클래스와 네임 스페이스를위한 것이 아닌가? 별도의 어셈블리를 사용하면 어떤 이점이 있습니까? 잠재적으로 더 작은 업그레이드 및 메모리 사용 (일부는로드되지 않은 경우)과 같은 일부를 생각할 수 있지만 컴파일하고 관리하는 데 100 개 이상의 어셈블리를 갖는 데는 확실히 비용이 듭니다.
si618

1
@Mark 나는 당신의 고통을 느낍니다. 여기에 최대 94 개의 프로젝트가 있습니다. 구조 조정을 위해 여러 팀의 개발을 중단해야했기 때문에 지금은 많은 일을 할 수 없습니다. 다른 91 개를 참조하는 3 개의 EXE 프로젝트가 있습니다. 하나의 공통 출력 폴더로 실험하고 있습니다. 지금까지 얻은 결과는 매우 인상적입니다.
Kevin

2
100 세 이상? 즉 ... 지금 여기에 거의 600을 밀어 ... 우리가 무엇을 위해 아무것도
C 존슨

답변:


41

내가 작성한이 두 MSBuild 문서에 관심이있을 수 있습니다.

MSBuild : 신뢰할 수있는 빌드를 만들기위한 모범 사례, 1 부

MSBuild : 안정적인 빌드를 만들기위한 모범 사례, 2 부

특히 Part 2에는 살펴 볼만한 대형 소스 트리 구축 섹션 이 있습니다.

여기에서 귀하의 질문에 간략하게 답변하려면 :

  • CopyLocal? 확실히 이거 끄세요
  • 하나 이상의 출력 폴더에 빌드 하시겠습니까? 하나의 출력 폴더로 빌드
  • 솔루션 폴더? 이것은 맛의 문제입니다.

이브라힘 하시 미

내 책 : Microsoft Build Engine 내부 : MSBuild 및 Team Foundation Build 사용


고마워요, 꼭 확인해 보겠습니다!
Eyvind

1
나는이 책과 그것의 굉장한 것을 가지고 있다고 말할 것이다. TFS 빌드와 로컬 개발자 빌드를 매우 광범위하게 자동화하는 데 도움이되었습니다. 저는 이제 증분 빌드 작업을하고 있으며이 책은 주제에 대해 매우 깊이 들어갑니다. 가격 가치가 있습니다. 감사합니다. 앞으로도 힘써주세요.
irperez

의견에 대한 감사 irperez
사예드 이브라힘 하시

2
CopyLocal을 비활성화하기위한 UNCONDITIONAL 권장 사항의 경우 -1입니다. Set CopyLocal = false로 인해 배포 중에 다른 문제가 발생할 수 있습니다. "서브 시퀀스를 이해하지 않는 한, false로 프로젝트 참조."내 블로그 게시물 "하지 변경"로컬 복사를 참조하십시오 ( geekswithblogs.net/mnf/archive/2012/12/09/... )
마이클 Freidgeim에게

여러 스레드로 컴파일 할 때 "하나의 출력 폴더로 빌드"하면 문제가 발생할 수 있습니까?
BrunoLM 2015-06-28

9

항목을 정리하는 데 도움이되는 솔루션 폴더를 절약 하려면 +1하십시오 .

프로젝트를 자체 폴더에 구축하려면 +1합니다. 우리는 처음에 공통 출력 폴더를 시도했으며 이로 인해 오래된 참조를 찾는 것이 미묘하고 고통 스러울 수 있습니다.

FWIW에서는 솔루션에 대한 프로젝트 참조를 사용합니다. 요즘에는 nuget이 더 나은 선택 일 수 있지만 svn : externals는 타사 및 (프레임 워크 유형) 사내 어셈블리 모두에서 잘 작동한다는 사실을 발견했습니다. svn : externals를 참조 할 때 HEAD 대신 특정 개정 번호를 사용하는 습관을들이십시오 (유죄 :).


2
+1 공통 출력 폴더 솔루션에도 문제가 있습니다. 나는 조금 더 설명해 주시겠습니까 어떤 수단 "솔루션에 대한 프로젝트 참조"이해하지 못했다 ...
마우 페르

에서와 같이 VS-> 참조 추가-> 찾아보기 대신 VS-> 참조 추가-> 프로젝트를 사용합니다. 내가 아는 작은 요점이지만 일부 사람들은 다르게 수행합니다 (그리고 이것이 더 많은 두통을 유발한다고 생각합니다). MSBuild csproj 텍스트를 보면 Reference 대신 ProjectReference 속성이 표시됩니다.
si618

흥미로운 대답! 나는 당신이 찌르는 곳을 찌르는 것 같아요. 솔루션 폴더가 전혀 없으며 프로젝트 이름 지정에 의존합니다 (프로젝트 이름은 네임 스페이스와 동일 함). 모든 출력이 단일 폴더로 이동하므로 개발자 설정이 배포 설정에 훨씬 더 가깝습니다. 종속성이 올바르게 설정되면 오래된 참조가 없습니다.
Thomas Bratt

예, 공통 출력 디렉토리는 특히 resharper를 사용할 때 많은 고통을 초래합니다. 참으로 오래된 참조.
Florian Doyon

1
@Kevin, 이제 몇 년이 지났지 만 기억에서 한 가지 예는 동일한 어셈블리를 참조하는 두 개의 프로젝트, 예를 들어 프로젝트가 참조되지 않는 외부 라이브러리입니다. 동일한 버전에 있으면 괜찮지 만이 라이브러리의 새 릴리스가 나오지만 하나의 프로젝트 만 참조를 업데이트합니다. 공통 출력 폴더에서 어떤 버전이 사용됩니까?
si618

8

자주 사용하지 않는 프로젝트를 언로드하고 SSD를 구입하십시오. SSD는 컴파일 시간을 향상시키지 않지만 Visual Studio는 열기 / 닫기 / 빌드가 두 배 더 빨라집니다.


3
프로젝트 언로드는 사용자 별 설정이므로 팀의 개발자는 관심있는 프로젝트 만로드 할 수 있습니다. 이것은 우리 팀을 정말로 도왔습니다.
페이지

당신은 솔루션로드 관리자 확장 사용할 수 있습니다 visualstudiogallery.msdn.microsoft.com/...를 기본적으로로드하지 무엇을 정의
마이클 Freidgeim

6

우리는 109 개의 개별 프로젝트를 처리해야하는 것과 비슷한 문제가 있습니다. 경험을 바탕으로 한 원래 질문에 답하려면 :

1. 프로젝트 간의 참조를 가장 잘 처리하는 방법

'참조 추가'컨텍스트 메뉴 옵션을 사용합니다. '프로젝트'를 선택하면 기본적으로 단일 글로벌 솔루션 파일에 종속성이 추가됩니다.

2. "로컬 복사"를 설정하거나 해제해야합니까?

우리의 경험에서 벗어났습니다. 추가 복사는 빌드 시간을 추가합니다.

3. 모든 프로젝트가 자체 폴더에 빌드되어야하거나 모두 동일한 출력 폴더에 빌드되어야합니까 (모두 동일한 애플리케이션의 일부 임)

모든 출력은 'bin'이라는 단일 폴더에 저장됩니다. 이 폴더는 소프트웨어가 배포 될 때와 동일하다는 생각입니다. 이렇게하면 개발자 설정이 배포 설정과 다를 때 발생하는 문제를 방지 할 수 있습니다.

4. 솔루션 폴더가 항목을 구성하는 좋은 방법입니까?

우리 경험으로는 아닙니다. 한 사람의 폴더 구조는 다른 사람의 악몽입니다. 깊이 중첩 된 폴더는 항목을 찾는 데 걸리는 시간을 증가시킵니다. 우리는 완전히 평평한 구조를 가지고 있지만 프로젝트 파일, 어셈블리 및 네임 스페이스의 이름을 동일하게 지정합니다.


프로젝트를 구조화하는 방법은 단일 솔루션 파일에 의존합니다. 프로젝트 자체가 변경되지 않았더라도이를 구축하는 데 오랜 시간이 걸립니다. 이를 돕기 위해 일반적으로 다른 '현재 작업 집합'솔루션 파일을 만듭니다. 우리가 작업중인 모든 프로젝트가 여기에 추가됩니다. 빌드 시간이 크게 개선되었지만 현재 세트에없는 프로젝트에 정의 된 유형에 대해 Intellisense가 실패한다는 문제점이 있습니다.

솔루션 레이아웃의 일부 예 :

\bin

OurStuff.SLN

OurStuff.App.Administrator
OurStuff.App.Common
OurStuff.App.Installer.Database
OurStuff.App.MediaPlayer
OurStuff.App.Operator
OurStuff.App.Service.Gateway
OurStuff.App.Service.CollectionStation
OurStuff.App.ServiceLocalLauncher
OurStuff.App.StackTester
OurStuff.Auditing
OurStuff.Data
OurStuff.Database
OurStuff.Database.Constants
OurStuff.Database.ObjectModel
OurStuff.Device
OurStuff.Device.Messaging
OurStuff.Diagnostics
...
[etc]

여러 스레드로 컴파일 할 때 "하나의 출력 폴더로 빌드"하면 문제가 발생할 수 있습니까?
BrunoLM

4

우리는 여기서 비슷한 대규모 프로젝트를 진행합니다. 솔루션 폴더는 사물을 정리하는 좋은 방법임이 입증되었으며 로컬 복사를 true로 설정하는 경향이 있습니다. 각 프로젝트는 자체 폴더에 빌드되며, 배포 가능한 각 프로젝트에 대해 올바른 바이너리 하위 집합이 있습니다.

시간 개방과 시간 구축에 관해서는 더 작은 솔루션으로 나누지 않고는 고치기가 어려울 것입니다. 여기서 속도를 향상시키기 위해 빌드 병렬화 (이 작업을 수행하고 UI에 통합하는 방법에 대해 Google "Parallel MS Build")를 조사 할 수 있습니다. 또한 디자인을 살펴보고 일부 프로젝트를 리팩토링하여 전체적으로 더 적은 수의 결과를 얻을 수 있는지 확인하십시오.


3

빌드 문제를 완화하는 측면에서 빌드에 "구성 관리자 ..."옵션을 사용하여 특정 프로젝트 빌드를 활성화 또는 비활성화 할 수 있습니다. 특정 프로젝트를 제외하고 특정 프로젝트를 대상으로 할 때 사용할 수있는 "프로젝트 [n] 빌드"를 가질 수 있습니다.

100 개 이상의 프로젝트가 진행되는 한, 솔루션 크기를 줄이는 이점에 대해이 질문에 당황하고 싶지 않다는 것을 알고 있지만로드 시간을 단축하는 데는 다른 옵션이 없다고 생각합니다. 메모리 사용량) devenv.


흠, 이것이 틀렸다거나 동의하지 않는다는 이유로 반대 투표를 받았습니까? 이유를 말씀해 주시면 전자와 함께 살 수 있습니다.
Michael Meadows

동의합니다, 나는 코멘트없이 반대 투표를 싫어합니다. 그래서 Michael 당신은 방정식의 균형을 맞추기 위해 나의 +1을 얻습니다 ;-)
si618

2
btw, 저는 개인적으로 이런 종류의 구성 관리를 다루고 싶지 않습니다. 왜? 실수로 수정 ​​된 구성을 커밋하면 빌드 서버 또는 다른 개발자가 영향을 받기 때문입니다.
si618

동의합니다. 실제로 프로젝트가 너무 많은 솔루션에도 동일한 문제가 적용됩니다. :)
Michael Meadows

3

일반적으로이 작업은 "디버그"프로세스가 실제로 어떻게 발생하는지에 따라 다릅니다. 일반적으로 copy local을 true로 설정하지 않습니다. 각 프로젝트의 빌드 디렉토리를 설정하여 모든 것을 원하는 끝점으로 출력합니다.

따라서 각 빌드 후에는 모든 dll 및 모든 Windows / 웹 응용 프로그램으로 채워진 폴더가 있으며 모든 항목이 적절한 위치에 있습니다. dll이 결국 올바른 위치에 있기 때문에 로컬 복사가 필요하지 않았습니다.

노트

위의 내용은 일반적으로 웹 응용 프로그램 인 내 솔루션에 적용되며 참조 관련 문제는 경험하지 않았지만 가능할 수 있습니다!


3

비슷한 문제가 있습니다. 우리는 더 작은 솔루션을 사용하여 해결합니다. 모든 것을 여는 마스터 솔루션이 있습니다. 하지만 성능. 그것은 나쁘다. 따라서 우리는 개발자 유형별로 더 작은 솔루션을 세분화합니다. 따라서 DB 개발자는 자신이 관심있는 프로젝트를로드하는 솔루션을 가지고 있습니다. 서비스 개발자와 UI 개발자는 동일합니다. 누군가가 매일 필요한 작업을 수행하기 위해 전체 솔루션을 열어야하는 경우는 드뭅니다. 만병 통치약이 아닙니다. 장점과 단점이 있습니다. 이 기사의 "다중 솔루션 모델" 을 참조하십시오 (VSS 사용에 대한 부분은 무시하십시오.).


2

이렇게 큰 솔루션을 사용하는 경우이를 분리하는 것이 가장 좋은 방법이라고 생각합니다. "솔루션"은 필요한 프로젝트와 문제 해결을 위해 작업하는 다른 부분을 모으는 장소로 생각할 수 있습니다. 100 개 이상의 프로젝트를 전체 문제의 일부에 대해서만 솔루션을 개발하는 데 특화된 여러 솔루션으로 나누면 필요한 프로젝트와의 상호 작용 속도를 높이고 문제 영역을 단순화하여 주어진 시간에 덜 처리 할 수 ​​있습니다.

각 솔루션은 담당하는 출력을 생성합니다. 이 출력에는 자동화 된 프로세스에서 설정할 수있는 버전 정보가 있어야합니다. 출력이 안정적이면 최신 내부 배포로 종속 프로젝트 및 솔루션의 참조를 업데이트 할 수 있습니다. 여전히 코드를 실행하고 소스에 액세스하려면 Visual Studio에서 참조 된 어셈블리로 들어가서 소스 코드를 가져올 수있는 Microsoft 기호 서버를 사용하여 실제로이 작업을 수행 할 수 있습니다.

인터페이스를 미리 지정하고 개발중인 어셈블리를 조롱하여 완료되지 않았지만 개발하려는 종속성을 기다리는 동안 동시 개발을 수행 할 수 있습니다.

이러한 방식으로 물리적으로 분석 할 때 전체적인 노력이 얼마나 복잡한 지에 대한 제한이 없기 때문에 이것이 모범 사례라고 생각합니다. 모든 프로젝트를 단일 솔루션에 넣으면 결국 상한선에 도달하게됩니다.

이 정보가 도움이되기를 바랍니다.


2

약 60 개 이상의 프로젝트가 있으며 솔루션 파일을 사용하지 않습니다. C # 및 VB.Net 프로젝트가 혼합되어 있습니다. 성능은 항상 문제였습니다. 우리는 모든 프로젝트를 동시에 진행하지 않습니다. 각 개발자는 작업중인 프로젝트를 기반으로 자체 솔루션 파일을 만듭니다. 솔루션 파일은 소스 제어에 체크인되지 않습니다.

모든 클래스 라이브러리 프로젝트는 소스 디렉토리의 루트에있는 CommonBin 폴더에 빌드됩니다. 실행 파일 / 웹 프로젝트는 개별 폴더에 빌드됩니다.

프로젝트 참조를 사용하지 않고 대신 CommonBin 폴더의 파일 기반 참조를 사용합니다. 프로젝트를 검사하고 빌드 순서를 결정하는 사용자 지정 MSBuild 작업을 작성했습니다.

우리는 이것을 몇 년 동안 사용해 왔으며 불만이 없습니다.


3
사용자 지정 msbuild 작업을 공유 하시겠습니까?
andreapier 2013 년

0

그것은 모두 솔루션과 프로젝트가 무엇인지에 대한 정의 및 견해와 관련이 있습니다. 제 생각에 해결책은 매우 구체적인 요구 사항을 해결하는 프로젝트의 논리적 그룹입니다. 우리는 대규모 인트라넷 애플리케이션을 개발합니다. 해당 인트라넷 내의 각 응용 프로그램에는 자체 솔루션이 있으며 exe 또는 Windows 서비스에 대한 프로젝트도 포함될 수 있습니다. 그리고 우리는 기본 클래스와 헬퍼, httphandlers / httpmodules와 같은 것들이있는 중앙 집중식 프레임 워크를 가지고 있습니다. 기본 프레임 워크는 상당히 크고 모든 애플리케이션에서 사용됩니다. 이러한 방식으로 많은 솔루션을 분할하면 대부분의 솔루션이 서로 관련이 없기 때문에 솔루션에 필요한 프로젝트의 양을 줄일 수 있습니다.

솔루션에 많은 프로젝트를 포함하는 것은 잘못된 디자인입니다. 솔루션 아래에 그렇게 많은 프로젝트를 가질 이유가 없어야합니다. 내가 보는 또 다른 문제는 프로젝트 참조에 관한 것입니다. 특히 솔루션을 더 작은 솔루션으로 나누고 싶은 경우에는 결국 당신을 망칠 수 있습니다.

제 조언은이를 수행하고 중앙 집중식 프레임 워크를 개발하는 것입니다 (원하는 경우 자체적으로 Enterprise Library 구현). GAC를 공유하거나 파일 위치를 직접 참조하여 중앙 저장소를 가질 수 있습니다. 중앙 집중식 비즈니스 개체에도 동일한 전술을 사용할 수 있습니다.

DLL을 직접 참조하려면 copy local false (c : \ mycompany \ bin \ mycompany.dll과 같은 위치)를 사용하여 프로젝트에서 참조 할 수 있습니다. 런타임은 GAC 또는 런타임 빈에없는 파일을 참조하도록 app.config 또는 web.config에 몇 가지 설정을 추가해야합니다. 실제로는 로컬 복사 여부 또는 dll이 bin에 있는지 또는 GAC에 있는지 여부는 중요하지 않습니다. 나는 로컬을 복사하고 지저분한 시스템을 갖는 것은 나쁜 습관이라고 생각합니다. 그래도 해당 어셈블리 중 하나에 디버그해야하는 경우 로컬을 임시로 복사해야 할 가능성이 높습니다.

GAC없이 DLL을 전역 적으로 사용하는 방법에 대한 내 기사를 읽을 수 있습니다. 저는 GAC가 xcopy 배포를 방지하고 응용 프로그램에서 자동 재시작을 트리거하지 않기 때문에 주로 GAC를 싫어합니다.

http://nbaked.wordpress.com/2010/03/28/gac-alternative/


0

CopyLocal = false를 설정하면 빌드 시간이 줄어들지 만 배포 시간 동안 다른 문제가 발생할 수 있습니다.

예를 들어 최상위 프로젝트, 두 번째 수준 종속성, 리플렉션에 의해 호출되는 DLL과 같이 로컬 복사 '를 True로 남겨야 할 때 많은 시나리오가 있습니다.

CopyLocal = false 설정에 대한 내 경험이 성공하지 못했습니다. 내 블로그 게시물 "하위 시퀀스를 이해하지 않는 한"로컬 복사 "프로젝트 참조를 거짓으로 변경하지 마십시오" 에서 장단점 요약을 참조하십시오 .

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.