开发者

Visual Studio solutions: Do these solutions have too many projects?

In the company I currently work for, we support 4 windows applications that are somewhat related. For each application we have a solution, each ranging from 50 to 100 projects. There are probably 40 or 50 projects that are shared between one or more solutions.

Just to give you an idea, the larger solution has almost 90 projects, 20 of which are UI projects (main application, custom controls projects, UI helper projects), another 20 are Business Layer projects, there's probably 30 or 40 Data Access layer projects and the rest are Windows Se开发者_运维问答rvice projects and specialized projects

I've always felt that there are too many projects in each solution. Sure, we're talking about large applications, but I don't see why many of the projects couldn't be consolidated. In my previous company, we actually had one single project for the business layer, one single project for the DAL and obviously one project for each windows or web app.

Here are some of the problems I've come across due to the large amount of projects:

  • Large compile times.
  • Classes that normally should be Private need to be Public in order to be accessible by other projects in the same layer.
  • I've recently started using the profiler Eqateq. The trial version allows profiling up to 10 dlls. My situation obviously complicates using this application.
  • Keeping track of the references between projects is quite complicated. I'm sure there are a lot of unused references between projects.

In contrast, I haven't found an advantage of this situation.

So, my questions are:

  • When do you decide to create a new project instead of maybe just creating a folder in the current project?
  • Are there any advantages that I'm overlooking?

UPDATE:

Keep in mind that I'm not proposing having one single project for everything. At a bare minimum, there should be one project for the DAL, one for the BL and one for every UI app. And I realize even that is unrealistic for most applications. What I'm trying to get at is, what are the best practices for defining the level of "single responsibility" for an assembly? I mean, this is a very subjective matter that, if taken to the extreme, would lead to having one assembly per class.

UPDATE 2:

All three answers provided valuable information, but as I can only select one I'm choosing Doc's for his comment on how to determine the number of DAL projects. I'm also linking to other questions I just found that have related information: Here and here. I also recommend reading this article.


We are talking mainly about .NET projects, right? Having your application split into different projects/assemblies forces you to avoid cyclic dependencies between those projects, since the C# and VB.NET compilers do prohibit this. If you put a everything into one big project, every class can reference every other class in that project, allowing you to create a real dependency nightmare. If you are going to use unit tests and development in a team, it is mostly easier if team members can work at different, isolated DLLs and test them separately.

The "keeping track of references" part of your question: if you put everything into one big DLL, you have the same references between your classes as if you have separate DLLs, but you cannot control them any more. Same goes for "private" classes (you mean "internal", I think?)

What I cannot tell you, of course, is, if your 90 projects are well chosen units of work. That's a question of "single responsibility", correct level of abstraction and resulting dependencies, only to be answered by someone who knows your application system in detail.

EDIT: so far I have read some articles (like this one) about bringing down compile times by defining the component boundaries by namespaces, and putting several components into one physical assembly / one VS project. To make this approach feasible, one needs probably a tool like NDepend or something similar to make sure there are no cyclic dependencies between components. For big projects, this may probably the better alternative.


It looks as though this is a classic example of pre-mature optimisation. Developers in your team seem to be creating many projects probably due to historic architectural reasons and you are doing the right thing by questioning this approach.

My personal opinion is to start with one project per layer (as you mention) like one for GUI, one for Business Layer, one for DAL etc. Additional projects for your solution should only be created when a specific need arises and not prematurely. At this point you can refactor your solution to move a project "Folder" into its own separate project.

This will ensure that : - build times are faster - You have the exact amount of projects your project requires - You have documented reasoning as to why you created a specific project (what need it fulfils)

Creating many specific projects in a solution is simply "Over engineering". You wouldn't over-engineer your code and create classes in places that were not required. You would refactor your code to include a class with a single responsibility when one was required. The same applies to solutions and projects.


Having many projects isn't necessarily bad.

A big advantage of it is having modules to create an architecture with layers. That is, you Gui classes can reference the lower layers, but not the opposite.

If you have a lower layer (business logic, for example) referencing an upper layer (gui) you will have a circular dependency and visual studio will refuse to build your solution.

This doesn't happen if you have all projects mixed into a single project. Surely you can spot this if you run DSM software on your code, but imo having your compiler to help you is safer.

About your point on having classes that could be private becoming public makes me think more about your API. Shouldn't these projects be merged together or shouldn't these classes be extracted into a 3rd project. I try to think on layers when thinking on these problems, there is no silver bullet thou.

For classes that belong ONLY to the project I usually add a "internal" (or "detail") word to the namespace of these "internal" classes that must be declared public. Eg.: you'll know that no classes from MyApplication.Model.Publisher should access any classes from: MyApplication.Model.Vendors.Internal. This a technique that I've seen at the Eclipse API.

I know C# has the internal keyword, but sometimes people will just declare it public without thinking about it. Having it on the name is a stronger approach since it takes more work to make that class public.

Other approaches with really huge software is going the plugins way, so it will make your build times much shorter. It always comes with a price thou. You can check OSGI for that.


If the number of projects in a given solution is causing daily annoyance (for example, due to solution load and compilation times), then you do indeed have too many projects in the solution. That said, the alternatives can be a bit annoying too, so you have to figure out where your "happy medium" lies.

Referencing pre-compiled assemblies instead of in-solution projects for at least a subset of projects is one approach that will reduce the number of projects without affecting any pre-existing decisions regarding segregation of functionality. It can also have other benefits, particularly in larger teams. For example, referenced assemblies can be published to the rest of the team after more rigourous testing instead of simply whenever a dev who works on one of the referenced projects happens to check a change into source control.

While cyclic dependency avoidance is definitely desirable, I've seen assembly segregation taken to some rather ridiculous extremes. There are tools (e.g.: NDepend, FxCop) that can help detect inappropriate dependencies, and I would generally tend to favour their use over assembly segregation when inappropriate dependency avoidance is the only reason for segregration.


I think the real issue here is one of single responsibility. I don't mean in terms of class design I mean the purpose of a .Net project.

Generally a project is used for:
1. Building some code to output a DLL, EXE, Website, API etc.
2. To control access to and structure code in a solution

From my experience, most projects are used for 2. What this leads to in large solutions is a very breadth-first structure that quickly becomes unintuitive, slows builds, slows visual studio (hello resharper!) means that huge amounts of dependencies get moved from bin to bin which makes all these DLLs that you don't actually need.

For example, if c# access modifiers could be expressed at namespace boundaries (instead of Project) then we wouldn't need to do this and could have meaningful intuitive namespace hierarchies where you would only need a project if you actually need to produce a DLL. Of course I haven't completely thought this through but I feel like something isn't quite right with having so many projects in a solution.

How does Java deal with this? Do large Java projects have lots of circular dependencies?

My answer to the question is to have as few Projects as you can get away with.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜