Many projects don’t lead to a good solution
Posted by Davy Brion on July 17th, 2008
Chad Myers discusses an extremely common anti-pattern in the .NET world that usually annoys the shit out of me: too many projects in a solution. I’ve seen it way too many times as well. A lot of people really want to split everything up into a bunch of assemblies while there’s usually no good reason whatsoever. Chad brings up a few issues about this approach, but there are more reasons not to like this.
For starters, i always feel like i’m getting lost in the Solution Explorer when i have to work with these kinds of solutions. Granted, i am a Mac user so that might have something to do with it. I gotta use Vista at work all day and after 3 weeks i still feel hopelessly lost in it. Anyways, easy navigation is very important to me. Especially for my productivity because every time i feel i’m wasting too much time looking for a specific file or a specific namespace of classes, it hurts my rhythm. And that rhythm is something you really don’t want to get disturbed by stupid little issues when you’re working on some interesting stuff. Granted, if the Solution Explorer was a bit nicer to use (Track Active Item sucks half the time, disabling it makes the other half suck) this probably wouldn’t be so big of an issue, but still, it’s important to me.
Secondly, many projects slows compilation time which hurts my TDD feedback loop. If you have a lot of projects in your solution your compilation time increases. If you’re doing TDD, you’re constantly adding/editing code and you’re constantly compiling to run a couple of tests. The difference in compilation time between 3 projects or 10 really adds up, even for one day. It leads to frustration, which leads to me taking more breaks from coding. Again, this breaks my rhythm of coding.
And finally, i’m getting tired of developers using purely theoretical arguments to defend practices/approaches that have no practical merit whatsoever (on a side note: i call this the Intellectual Masturbation Syndrome). How often have you heard people say “oh but i want to be able to reuse these bunch of classes somewhere else later on without having references to all this other stuff as well”. I’ve heard it far too many times, and i’ve almost NEVER seen anyone actually reuse one of those assemblies somewhere else. If you do need it somewhere else later on, split it up at that point. You actually have a valid reason to do so in that situation. But no earlier than that. Or the typical “i think every layer should be in it’s own assembly”. Yeah that sounds good and all, but i’ve never seen a real benefit to doing that. If you’re worried about your developers using classes from layers in places where they shouldn’t be using those classes, you probably have bigger things to worry about. How about teaching them why they shouldn’t do that instead of just preventing them from doing it? If you don’t trust your developers, they will always disappoint you. Trust them and more importantly, teach them.
So here’s my recommendation: ONE project per physical deployment. That’s right. A web application that doesn’t use a remote service? One assembly. A fat client windows app? One assembly. A smart client windows app? One assembly for the client, one for each application-server deployment and one more assembly for types that are shared between the client and the server. So if you’re hosting 10 services on one application server, just go for one assembly server-side. Add another project for your tests, and you should normally end up with between 2 and 5 projects in your solution, depending on how many physical deployments you have.
Btw, i’m currently using two projects for tests… i have a
July 18th, 2008 at 7:43 am
IMS! Nice term
July 18th, 2008 at 4:49 pm
[...] Many Projects Don’t Lead to a Good Solution (Davy Brion) [...]
July 18th, 2008 at 5:24 pm
Here’s my issues with the less projects discussion:
1) Less project doesn’t really, in my experience, lead to easy navigation on a large project. You just end up with more folders and more folder hierarchy which mean that related classes spread out more. So if you keep all your domain classes in a folder then that folder will be large or have a lot of hierarchy, do the same with other aspects of the codebase (controllers, views, factories, config…) you end up navigating around a lot anyway.
2) Less project is faster - Agreed, but then by splitting things out into small(er) coherent chunks you can include just what you need in the solution. I don’t bring in a mothership project with all its tests/code just so I can reuse the projects that I really am interested in. Also I think Michael Feathers had an interesting point on this in his book, where you only depend on an interface and as long as the implementation doesn’t change you don’t need to rebuild.
3) Reuse - I haven’t experienced people moving things out for future reuse but I agree that’s bad, however in my experience reuse happens a lot and thats definitely a place where more targetted projects help.
4) Layer Per Assembly - I agree, basically, with that approach and its not about trust, I’d do it working on my own as I just find it far cleanrer.
Anyway I’m not overly happy with a lot of projects but one project doesn’t fit my needs either (reuse/dependencies/navigation) so I’m really wondering if we need a more virtualized view. Folders/projects providing one view of our development efforts just doesn’t seem enough…
July 18th, 2008 at 5:32 pm
Just remember, however, that it becomes impossible to patch your installation if everything is one big assembly. Depending on client requirements (especially downtime requirements) patching (via MSI) a single assembly to fix a bug can be very useful.
July 18th, 2008 at 5:37 pm
Just re-read, when I said “I don’t bring in a mothership project with all its tests/code just so I can reuse the projects that I really am interested in” I meant “reuse the parts”.
Got projects on the brain today.
July 18th, 2008 at 9:14 pm
Intellectual Masturbation Syndrome…almost fell out of my chair laughing. I used to reach Intellectual Climax on a regular basis but have since come around to as few projects as possible. Two to five sounds about right. I too have almost never re-used any code I have written across applications. When I need to I will create a Bill.Commons project but until then I’ll stick with the CCCV Pattern for the small amount of code I re-use.
July 19th, 2008 at 1:21 pm
@Colin:
About the navigation… i think it really depends on a lot of things. i wouldn’t just use a couple of top-level folders and put everything directly underneith them either. I pretty much go with top level folders for everything that most people would use different projects for and then i probably have a similar folder structure as most people would have. I just find it a lot easier to have it all within the same project. It’s probably just me though
As for reuse, i agree that once you want to reuse certain parts that would be a valid reason to put those parts in a separate project. I don’t think it should be a rule though… if there’s an advantage to splitting it up for reuse then by all means do so. If there’s really no disadvantage to referencing an entire assembly just to reuse a couple of classes, then i don’t really see the point in splitting it up either. It’s something you should look at on a case by case basis probably
the layer per assembly thing… i still don’t see the point as the whole “it’s cleaner” argument just seems purely theoretical to me. As long as there is no practical advantage, i don’t see the point. Obviously, this changes when you have multiple physical deployments, but if that’s not the case, why bother?
@LukeB:
Wouldn’t the client’s application have to be restarted anyway before the fixed assembly would be used by the application? It might as well be just one assembly then
Unless you ment updating a server-side assembly without affecting client downtime, but then you’d already be using different assemblies anyway
July 21st, 2008 at 6:16 pm
[...] Many projects don’t lead to a good solution Response to above link. [...]