In the world of Visual Studio we have solutions and projects. I create lots of projects. At Eleutian we have close to 40 projects in our main solution. Keep in mind, that at any given time I only have a subset those loaded depending on which feature I am working on. Machine, a relatively recent undertaking, is growing and is already up to 13 projects. I've been thinking of the higher level organization of my software development process and come to some conclusions. As I'm working on a piece of software there are two primary reasons for why I create a new project:
- Do I need a place to store tests for another project? Nearly half of all the projects I create are test projects. :)
- Do I have a group of classes that can be packaged and then later re-used? I see this situation as an application of Separation of Concerns.
Number two is particularly important. Projects to me are a useful way to create distinct, reusable collections of code. Separate projects are good ways of isolating heavy dependencies. Storing static code in a separate project is a good way to decrease time spent during rebuilds. In a client-server situation it's handy to place code common to both tiers in a shared project. Projects are wonderful tools for good design and lately I've been wishing I had more control over them.
Visual Studio enforces a strict one assembly per project convention. Remember, we can change preprocessing settings, target CPU, debug/optimization settings, and a few other things via Build Configurations. In my experience the one-to-one convention creates some problems:
- A lot of project configuration is duplicated. Most of my projects have the same core build configuration and only a few are different and then only in minor ways. I've often wished I could create my Build Configurations and then reference them from my projects.
- They get in the way! For me, projects are usually created once and forgotten. Most of my project-level changes are rare. Yet, they are everywhere in the user interface. Thankfully with R# I can GotoType around them, but I still feel like they stand between me and the code. I'm weird that way I guess. My focus is the code, not the projects.
- In order to build or use code under two different project-configurations I'm usually required to perform some kind of trickery. Refactoring code into a common project that is referenced by two others, for example. I've even had to create two csproj's in one directory that both include the same code, this is awkward.
I want two things. I want something slightly lower on the hierarchy than a project - a sub-project. We could, for example, group tests into a sub project and the production code into another. Much of the existing project configuration would be shared among them, including dependencies and the active build configuration. Additionally, and this is huge, I would get rid of the parent-child relationship between projects and code. Projects would become external configuration that would be applied to sets of code.
I used to do lots of Java development and because of the atomic nature of the .class files this kind of structure was very easy. A single project can result in multiple jar files from which classes can be included/excluded at will. I'm really proposing a more shallow solution hierarchy. How sub-projects would look in VS I can't say. Thankfully, this is not a limitation of C# or .NET. The fact is, we can probably achieve a very rudimentary implementation of this via some clever tweaking of the standard .targets files.
I'm curious about how much I would like this approach in practice. You never know how much you'll like something until you've tried it. I do know that when I used Java I didn't wish for the VS approach. Any thoughts? Is this too much? Is this not enough?
Posted
04-01-2008 5:39 PM
by
jlewallen