Visual Studio (2008)의 대규모 솔루션에 대한 모범 사례
약 100 개 이상의 프로젝트 (대부분 C #)로 구성된 솔루션이 있습니다. 당연히 개봉하고 구축하는 데 시간이 오래 걸리므로 그런 짐승에 대한 모범 사례를 찾고 있습니다. 답변을 얻고 자하는 질문에는 다음과 같은 것들이 있습니다.
- 프로젝트 간의 참조를 가장 잘 처리하는 방법
- "로컬 복사"가 켜져 있거나 꺼져 있어야합니까?
모든 프로젝트가 자체 폴더에 빌드되어야하는지 아니면 모두 동일한 출력 폴더에 빌드되어야 하는가 (모두 동일한 애플리케이션의 일부 임)
솔루션 폴더가 물건을 정리하는 좋은 방법입니까?
솔루션을 여러 개의 작은 솔루션으로 분할하는 것이 옵션이라는 것을 알고 있지만 자체 리팩토링 및 구축 문제가 있으므로 별도의 스레드에 대해 저장할 수 있습니다. :-)
내가 작성한이 두 MSBuild 기사에 관심이있을 수 있습니다.
MSBuild : 신뢰할 수있는 빌드를 만들기위한 모범 사례, 1 부
MSBuild : 신뢰할 수있는 빌드를 만들기위한 모범 사례, 2 부
특히 Part 2에는 살펴 볼만한 대형 소스 트리 구축 섹션 이 있습니다.
여기에서 귀하의 질문에 간략하게 답변하려면 :
- CopyLocal? 확실히 이거 끄세요
- 하나 이상의 출력 폴더에 빌드 하시겠습니까? 하나의 출력 폴더로 빌드
- 솔루션 폴더? 이것은 맛의 문제입니다.
이브라힘 하시 미
내 책 : Microsoft Build Engine 내부 : MSBuild 및 Team Foundation Build 사용
항목을 정리하는 데 도움이되는 솔루션 폴더를 절약 하려면 +1하십시오 .
프로젝트를 자체 폴더에 구축하는 경우 +1. 우리는 처음에 공통 출력 폴더를 시도했으며 이로 인해 오래된 참조를 찾는 것이 미묘하고 고통 스러울 수 있습니다.
FWIW에서는 솔루션에 대한 프로젝트 참조를 사용합니다. 요즘에는 nuget이 더 나은 선택 일 수 있지만 svn : externals가 타사 및 (프레임 워크 유형) 사내 어셈블리 모두에서 잘 작동한다는 사실을 발견했습니다. svn : externals를 참조 할 때 HEAD 대신 특정 개정 번호를 사용하는 습관을들이십시오 (유죄 :).
자주 사용하지 않는 프로젝트를 언로드하고 SSD를 구입하십시오. SSD는 컴파일 시간을 향상시키지 않지만 Visual Studio는 열기 / 닫기 / 빌드가 두 배 빨라집니다.
우리는 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]
We work on a similar large project here. Solution folders has proved to be a good way of organising things, and we tend to just leave copy local set to true. Each project builds to its own folder, and then we know for each deployable project in there we have the correct subset of the binaries in place.
As for the time opening and time building, that's going to be hard to fix without breaking into smaller solutions. You could investigate parallelising the build (google "Parallel MS Build" for a way of doing this and integrating into the UI) to improve speed here. Also, look at the design and see if refactoring some of your projects to result in fewer overall might help.
In terms of easing the building pain, you can use the "Configuration Manager..." option for builds to enable or disable building of specific projects. You can have a "Project [n] Build" that could exclude certain projects and use that when you're targeting specific projects.
As far as the 100+ projects goes, I know you don't want to get hammered in this question about the benefits of cutting down your solution size, but I think you have no other option when it comes to speeding up load time (and memory usage) of devenv.
What I typically do with this depends a bit on how the "debug" process actually happens. Typically though I do NOT set copy local to be true. I setup the build directory for each project to output everything to the desired end point.
Therefore after each build I have a populated folder with all dll's and any windows/web application and all items are in the proper location. Copy local wasn't needed since the dll's end up in the right place in the end.
Note
The above works for my solutions, which typically are web applications and I have not experienced any issues with references, but it might be possible!
We have a similar issue. We solve it using smaller solutions. We have a master solution that opens everything. But perf. on that is bad. So, we segment up smaller solutions by developer type. So, DB developers have a solution that loads the projects they care about, service developers and UI developers the same thing. It's rare when somebody has to open up the whole solution to get what they need done on a day to day basis. It's not a panacea -- it has it's upsides and downsides. See "multi-solution model" in this article (ignore the part about using VSS :)
I think with solutions this large the best practice should be to break them up. You can think of the "solution" as a place to bring together the necessary projects and perhaps other pieces to work on a solution to a problem. By breaking the 100+ projects into multiple solutions specialized to developing solutions for only a part of the overall problem you can deal with less at a given time there by speeding your interactions with the required projects and simplifying the problem domain.
Each solution would produce the output which it is responsible for. This output should have version information which can be set in an automated process. When the output is stable you can updated the references in dependent projects and solutions with the latest internal distribution. If you still want to step into the code and access the source you can actually do this with the Microsoft symbol server which Visual Studio can use to allow you to step into referenced assemblies and even fetch the source code.
Simultaneous development can be done by specifying interfaces upfront and mocking out the assemblies under development while you are waiting for dependencies that are not complete but you wish to develop against.
I find this to be a best practice because there is no limit to how complex the overall effort can get when you break down it down physically in this manner. Putting all the projects into a single solution will eventually hit an upper limit.
Hope this information helps.
We have about 60+ projects and we don't use solution files. We have a mix of C# and VB.Net projects. The performance was always an issue. We don't work on all the projects at the same time. Each developer creates their own solution files based on the projects they're working on. The solution files doesn't get checked into our source control.
All Class library projects would build to a CommonBin folder at the root of the source directory. Executable / Web Projects build to their individual folder.
We don't use project references, instead file based reference from the CommonBin folder. I wrote a custom MSBuild Task that would inspect the projects and determine the build order.
We have been using this for few years now and have no complaints.
It all has to do with your definition and view on what a solution and a project are. In my mind a solution is just that, a logical grouping of projects that solve a very specific requirement. We develop a large Intranet application. Each application within that Intranet has it's own solution, which may also contain projects for exes or windows services. And then we have a centralized framework with things like base classes and helpers and httphandlers/httpmodules. The base framework is fairly large and is used by all applications. By splitting up the many solutions in this way you reduce the amount of projects required by a solution, as most of them have nothing to do with one another.
Having that many projects in a solution is just bad design. There should be no reason to have that many projects under a solution. The other problem I see is with project references, they can really screw you up eventually, especially if you ever want to split up your solution into smaller ones.
My advice is to do this and develop a centralized framework (your own implementation of Enterprise Library if you will). You can either GAC it to share or you can directly reference the file location so that you have a central store. You could use the same tactic for centralized business objects as well.
If you want to directly reference the DLL you will want to reference it in your project with copy local false (somewhere like c:\mycompany\bin\mycompany.dll). A runtime you will need to add some settings to your app.config or web.config to make it reference a file not in the GAC or runtime bin. In all actuality it doesn't matter if it's copy local or not, or if the dll ends up in the bin or is even in the GAC, because the config will override both of those. I think it is bad practice to copy local and have a messy system. You will most likely have to copy local temporarily if you need to debug into one of those assemblies though.
You can read my article on how to use a DLL globally without the GAC. I really dislike the GAC mostly because it prevents xcopy deployment and does not trigger an autorestart on applications.
http://nbaked.wordpress.com/2010/03/28/gac-alternative/
Set CopyLocal=false will reduce build time, but can cause different issues during deployment time.
There are many scenarios, when you need to have Copy Local’ left to True, e.g. Top-level projects, Second-level dependencies, DLLs called by reflection.
My experience with setting CopyLocal=false wasn't successful. See summary of pro and cons in my blog post "Do NOT Change "Copy Local” project references to false, unless understand subsequences."
참고URL : https://stackoverflow.com/questions/690033/best-practices-for-large-solutions-in-visual-studio-2008
'developer tip' 카테고리의 다른 글
tr 요소 주변의 테두리가 표시되지 않습니까? (0) | 2020.09.18 |
---|---|
Angularjs 동적 ng- 패턴 유효성 검사 (0) | 2020.09.18 |
Xcode에서 C ++ 11을 사용할 수 있습니까? (0) | 2020.09.17 |
HTML5 / XHTML 역할 속성은 어떤 값을 가질 수 있습니까? (0) | 2020.09.17 |
htaccess에서 AuthUserFile과 함께 RELATIVE 경로를 사용하는 방법은 무엇입니까? (0) | 2020.09.17 |