Structuring projects & dependencies of large winforms applications in C# - visual-studio

UPDATE:
This is one of my most-visited questions, and yet I still haven't really found a satisfactory solution for my project. One idea I read in an answer to another question is to create a tool which can build solutions 'on the fly' for projects that you pick from a list. I have yet to try that though.
How do you structure a very large application?
Multiple smallish projects/assemblies in one big solution?
A few big projects?
One solution per project?
And how do you manage dependencies in the case where you don't have one solution.
Note: I'm looking for advice based on experience, not answers you found on Google (I can do that myself).
I'm currently working on an application which has upward of 80 dlls, each in its own solution. Managing the dependencies is almost a full time job. There is a custom in-house 'source control' with added functionality for copying dependency dlls all over the place. Seems like a sub-optimum solution to me, but is there a better way? Working on a solution with 80 projects would be pretty rough in practice, I fear.
(Context: winforms, not web)
EDIT: (If you think this is a different question, leave me a comment)
It seems to me that there are interdependencies between:
Project/Solution structure for an application
Folder/File structure
Branch structure for source control (if you use branching)
But I have great difficulty separating these out to consider them individually, if that is even possible.
I have asked another related question here.

Source Control
We have 20 or 30 projects being built into 4 or 5 discrete solutions. We are using Subversion for SCM.
1) We have one tree in SVN containing all the projects organised logically by namespace and project name. There is a .sln at the root that will build them all, but that is not a requirement.
2) For each actual solution we have a new trunks folder in SVN with SVN:External references to all the required projects so that they get updated from their locations under the main tree.
3) In each solution is the .sln file plus a few other required files, plus any code that is unique to that solution and not shared across solutions.
Having many smaller projects is a bit of a pain at times (for example the TortoiseSVN update messages get messy with all those external links) but does have the huge advantage that dependancies are not allowed to be circular, so our UI projects depend on the BO projects but the BO projects cannot reference the UI (and nor should they!).
Architecture
We have completely switched over to using MS SCSF and CAB enterprise pattern to manage the way our various projects combine and interact in a Win Forms interface. I am unsure if you have the same problems (multiple modules need to share space in a common forms environment) but if you do then this may well bring some sanity and convention to how you architect and assemble your solutions.
I mention that because SCSF tends to merge BO and UI type functions into the same module, whereas previously we maintained a strict 3 level policy:
FW - Framework code. Code whose function relates to software concerns.
BO - Business Objects. Code whose function relates to problem domain concerns.
UI - Code which relates to the UI.
In that scenario dependancies are strictly UI -> BO -> FW
We have found that we can maintain that structure even while using SCSF generated modules so all is good in the world :-)

To manage dependencies, whatever the number of assemblies/namespaces/projects you have, you can have a glance at the tool NDepend.
Personnaly, I foster few large projects, within one or several solutions if needed. I wrote about my motivations to do so here: Benefit from the C# and VB.NET compilers perf

I think it's quite important that you have a solution that contains all your 80 projects, even if most developers use other solutions most of the time. In my experience, I tend to work with one large solution, but to avoid the pain of rebuilding all the projects each time I hit F5, I go to Solution Explorer, right-click on the projects I'm not interested in right now, and do "Unload Project". That way, the project stays in the solution but it doesn't cost me anything.
Having said that, 80 is a large number. Depending on how well those 80 break down into dicrete subsystems, I might also create other solution files that each contain a meaningful subset. That would save me the effort of lots of right-click/Unload operations. Nevertheless, the fact that you'd have one big solution means there's always a definitive view of their inter-dependencies.
In all the source control systems that I've worked with, their VS integration chooses to put the .sln file in source control, and many don't work properly unless that .sln file is in source control. I find that intriguing, since the .sln file used to be considered a personal thing, rather than a project-wide thing. I think the only kind of .sln file that definitely merits source control is the "one-big-solution" that contains all projects. You can use it for automated builds, for example. As I said, individuals might create their own solutions for convenience, and I'm not against those going into source control, but they're more meaningful to individuals than to the project.

I think the best solution is to break it in to smaller solutions. At the company I currently work for, we have the same problem; 80 projects++ in on solution. What we have done, is to split into several smaller solutions with projects belonging together. Dependent dll's from other projects are built and linked in to the project and checked in to the source control system together with the project. It uses more disk space, but disk is cheap. Doing it this way, we can stay with version 1 of a project until upgrading to version 1.5 is absolutely necessary. You still have the job with adding dll's when deciding to upgrade to a other version of the dll though. There is a project on google code called TreeFrog that shows how to structure the solution and development tree. It doesn't contain mush documentation yet, but I guess you can get a idea of how to do it by looking at the structure.

A method that i've seen work well is having one big solution which contains all the projects, for allowing a project wide build to be tested (No one really used this to build on though as it was too big.), and then having smaller projects for developers to use which had various related projects grouped together.
These did have depencies on other projects but, unless the interfaces changed, or they needed to update the version of the dll they were using, they could continue to use the smaller projects without worrying about everything else.
Thus they could check-in projects while they were working on them, and then pin them (after changing the version number), when other users should start using them.
Finally once or twice a week or even more frequently the entire solution was rebuild using pinned code only, thus checking if the integration was working correctly, and giving testers a good build to test against.
We often found that huge sections of code didn't change frequently, so it was pointless loading it all the time. (When you're working on the smaller projects.)
Another advantage of using this approach is in certain cases we had pieces of functionality which took months to complete, by using the above approach meant this could continue without interrupting other streams of work.
I guess one key criteria for this is not having lots of cross dependencies all over your solutions, if you do, this approach might not be appropriate, if however the dependencies are more limited, then this might be the way to go.

For a couple of systems I've worked on we had different solutions for different components. Each solution had a common Output folder (with Debug and Release sub-folders)
We used project references within a solution and file references between them. Each project used Reference Paths to locate the assemblies from other solutions. We had to manually edit the .csproj.user files to add a $(Configuration) msbuild variable to the reference paths as VS insists on validating the path.
For builds outside of VS I've written msbuild scripts that recursively identify project dependencies, fetch them from subversion and build them.

I gave up on project references (although your macros sound wonderful) for the following reasons:
It wasn't easy to switch between different solutions where sometimes dependency projects existed and sometimes didn't.
Needed to be able to open the project by itself and build it, and deploy it independently from other projects. If built with project references, this sometimes caused issues with deployment, because a project reference caused it to look for a specific version or higher, or something like that. It limited the mix and match ability to swap in and out different versions of dependencies.
Also, I had projects pointing to different .NET Framework versions, and so a true project reference wasn't always happening anyways.
(FYI, everything I have done is for VB.NET, so not sure if any subtle difference in behavior for C#)
So, I:
I build against any project that is open in the solution, and those that aren't, from a global folder, like C:\GlobalAssemblies
My continuous integration server keeps this up to date on a network share, and I have a batch file to sync anything new to my local folder.
I have another local folder like C:\GlobalAssembliesDebug where each project has a post build step that copies its bin folder's contents to this debug folder, only when in DEBUG mode.
Each project has these two global folders added to their reference paths. (First the C:\GlobalAssembliesDebug, and then C:\GlobalAssemblies). I have to manually add this reference paths to the .vbproj files, because Visual Studio's UI addes them to the .vbprojuser file instead.
I have a pre-build step that, if in RELEASE mode, deletes the contents from C:\GlobalAssembliesDebug.
In any project that is the host project, if there are non dlls that I need to copy (text files outputted to other project's bin folders that I need), then I put a prebuild step on that project to copy them into the host project.
I have to manually specify the project dependencies in the solution properties, to get them to build in the correct order.
So, what this does is:
Allows me to use projects in any solution without messing around with project references.
Visual Studio still lets me step into dependency projects that are open in the solution.
In DEBUG mode, it builds against open loaded projects. So, first it looks to the C:\GlobalAssembliesDebug, then if not there, to C:\GlobalAssemblies
In RELEASE mode, since it deletes everything from C:\GlobalAssembliesDebug, it only looks to C:\GlobalAssemblies. The reason I want this is so that released builds aren't built against anything that was temporarily changed in my solution.
It is easy to load and unload projects without much effort.
Of course, it isn't perfect. The debugging experience is not as nice as a project reference. (Can't do things like "go to definition" and have it work right), and some other little quirky things.
Anyways, that's where I am on my attempt to make things work for the best for us.

We have one gigantic solution on the source control, on the main branch.
But, every developer/team working on the smaller part of the project, has its own branch which contains one solution with only few projects which are needed. In that way, that solution is small enough to be easily maintenaced, and do not influence on the other projects/dlls in the larger solution.
However, there is one condition for this: there shouldn't be too much interconnected projects within solution.

OK, having digested this information, and also answers to this question about project references, I'm currently working with this configuration, which seems to 'work for me':
One big solution, containing the application project and all the dependency assembly projects
I've kept all project references, with some extra tweaking of manual dependencies (right click on project) for some dynamically instantiated assemblies.
I've got three Solution folders (_Working, Synchronised and Xternal) - given that my source control isn't integrated with VS (sob), this allows me to quickly drag and drop projects between _Working and Synchronised so I don't lose track of changes. The XTernal folder is for assemblies that 'belong' to colleagues.
I've created myself a 'WorkingSetOnly' configuration (last option in Debug/Release drop-down), which allows me to limit the projects which are rebuilt on F5/F6.
As far as disk is concerned, I have all my projects folders in just one of a few folders (so just one level of categorisation above projects)
All projects build (dll, pdb & xml) to the same output folder, and have the same folder as a reference path. (And all references are set to Don't copy) - this leaves me the choice of dropping a project from my solution and easily switching to file reference (I've got a macro for that).
At the same level as my 'Projects' folder, I have a 'Solutions' folder, where I maintain individual solutions for some assemblies - together with Test code (for example) and documentation/design etc specific to the assembly.
This configuration seems to be working ok for me at the moment, but the big test will be trying to sell it to my colleagues, and seeing if it will fly as a team setup.
Currently unresolved drawbacks:
I still have a problem with the individual assembly solutions, as I don't always want to include all the dependent projects. This creates a conflict with the 'master' solution. I've worked around this with (again) a macro which converts broken project references to file references, and restores file references to project references if the project is added back.
There's unfortunately no way (that I've found so far) of linking Build Configuration to Solution Folders - it would be useful to be able to say 'build everything in this folder' - as it stands, I have to update this by hand (painful, and easy to forget). (You can right click on a Solution Folder to build, but that doesn't handle the F5 scenario)
There is a (minor) bug in the Solution folder implementation which means that when you re-open a solution, the projects are shown in the order they were added, and not in alphabetical order. (I've opened a bug with MS, apparently now corrected, but I guess for VS2010)
I had to uninstall the CodeRushXPress add-in, because it was choking on all that code, but this was before having modified the build config, so I'm going to give it another try.
Summary - things I didn't know before asking this question which have proved useful:
Use of solution folders to organise solutions without messing with disk
Creation of build configurations to exclude some projects
Being able to manually define dependencies between projects, even if they are using file references
This is my most popular question, so I hope this answer helps readers. I'm still very interested in further feedback from other users.

Related

Possible issues with multiple solution files for the same set of projects

Is there a list of all (or nearly all) possible issues that could stem from maintaining multiple solution files for the same set of projects? The only reason for doing so is different versions of Visual Studio.
I'm aware of the glaring issue where new projects are added in one solution file, that haven't been synced to the other. What are some others?
disclaimer: my current company is still entrenched using VS10, for mainly political reasons. so please, save the preaching about the need for having a single solution and how this is not the optimal "solution".
I've seen this done all the time, for the most part it is perfectly fine other than what you mentioned, any files added would have to be added to all of the projects. However, I would recommend you go with a make file of sorts, CMake is a very robust version but there are plenty of others. The way they work is basically, you write one script that defines how the project is to be made, then the end-user runs CMake.exe on it. It will take that script and generate the proper solution and project files for your entire project in the version of VS you want, it also supports generation of types like XCode and Eclipse solutions etc so it is very multi-platform.

Mono fo Android - One Solution for many clients

I have created three different solutions for three different clients, but those solutions are for an app that have the same features, classes, methods, resolution, except for the images, XML resource files, and a web service reference, that are specific for each one.
I would like to have just one solution for all those apps, that I could open in VS2010 IDE for edition, without errors. So, when I need to build or publish an specific app, I just set the client which one I need to, and go ahead to building or publishing.
It is important to consider that XML file names will be the same, as classes and images names too. The difference will be the content, but the name will always be the same.
My intention is to reduce my effort to maintain many solutions, having just one solution to work with.
In my company, we will have more than those three clients soon, so I am worried about how to maintain that. The best way will be have just one solution and when I need to generate a new app for a new client, I have just to change/include a few things (like some resources and images) and compile to a new client folder.
Is it possible? If so how?
One option would be to have a master solution which had the following
A "Template" project that contained your actual application and all of the shared code
Projects for all of your clients
In the projects for your clients, you could have links to the files in your files that come from your shared project. Then, in each of those projects, you could add the files that are only specific to them.
With this kind of structure, whenever you made a change to your Template project, all of the client projects would be updated as well because they just have pointers back to the Template project.
A good reference for this kind of setup would be the Json.Net Code Base. There he has a solution and project for all of the different configurations, but they all share the same files.
In terms of ensuring that the xml files are named properly, you might just want to put some checks into your main application to ensure that it has all of the files needed or potentially add a check into your build process.
There are many ways you could look to tackle this.
My favorite would be to run some sort of pre-build step - probably outside of Visual Studio - which simply replaces the files with the correct ones before you do a build. This would be easy to automate and easy to scale.
If you are going to be building for many more than three customers, then I think you should look to switch from Visual Studio building to some other automated build system - e.g. MSBuild from the command line or from something like TeamCity or CruiseControl. You'll find it much easier to scale if your build is automated (and robust)
If you don't like the file idea, then there are plenty of other things you could try:
You could try doing a similar step to above, but could do it inside VS using a pre-Build step.
You could use Conditional nodes within the .csproj file to switch files via a project configuration
You could look to shift the client-specific resources into another assembly - and then use GetResourceStream (or similar) at runtime to extract the resources.
But none of these feel as nice to me!

Add all projects to same solution or not?

I am the intranet developer for the company I work for and I have been doing this for the last 5 years. My projects are divided into two solutions, the "Intranet" solution itself and the "Library" solution. The "Library" sln itself has several projects containing the DAL, BLL, etc.. The reason why I kept them in a different solution is because I thought that "maybe", one day my library sln can be used in other projects as well - you know reuse the code that I already wrote :) Well, that never happened. Now, since its so easier to have all projects in the same .sln, I am thinking to just do that. Is that a wise situation? What would you do if you were in my shoes?
In the past I've used and reused the same 'project' in multiple solutions - I really just see a solution as a 'particular' instance of a collection of projects.
For example, we might have different solutions for the same overall piece of software depending on whether we want to be doing unit testing (in their own project) and or integration testing (in a separate project), and we'd open the right solution for what it is we're about to do. That way if you're doing normal coding with unit testing you don't have to build the integration test code every time and visa-versa.
Only thing to watch out for is bringing in a project to a solution that is a dependency of lots of other projects/solutions and then "accidentally" changing the code in it without realising it's in a side project rather than your main code. Then you can start breaking loads of other projects that depend on it and not realise!
Yes, you can do it! You may still reuse your DAL and BLL, as the project settings are stored in the specific project files (csproj, vbproj, ...). Also dependencies are stored there, so no problem and good to go. I have an addin-infrastructure and for every and each addin-package, I do need the addin-host, which is included in several solution files. I never experienced any problems with this. Open up your *.sln file in a text-editor to see its contents...just links to the projects.
Simply add your library projects to your intranet sln. Keep your library solution as is.
I would personally all add them to the same solution, yes. Namely, it doesn't matter if you plan on using some of the libraries in the solution in other projects: you can still add the compiled dll to those solutions, or you have the option to add them as an exisiting project to the new solutions.
So yes, I add everything to the same solution: gui-projects, libraries, even unit tests. Maybe if your solution becomes incredibly large (20+ projects, or larger) it would be better to split them up, but I've never worked on such large projects.
I prefer to have 2 solutions. They both have identical structure (more or less) but the 2nd contains reusable infrastructure code only that isn't tied to a particular project. The thing is - your project code shouldn't contain framework-like (i.e. 'IsNumeric()' string extension method) stuff next to serious banking business logic (even if you won't reuse your 'Library'). That just makes things much more readable and maintainable.
For example:
Solution1:
ProjectName.Core
ProjectName.Infrastructure
ProjectName.Application
ProjectName.UI
ProjectName.IntegrationTests
ProjectName.UnitTests
And
Solution2:
CompanyName.Core
CompanyName.Infrastructure
CompanyName.Application
CompanyName.UI
CompanyName.Tests
And I try not to have more than 10 projects in 1 solution. Otherwise - it leads to infinite toggling between "unload project"/"reload project.
I, for my part, have separated the Solutions and the projects, leaving me with a big punch of projects and only a few solution-files. I add all the projects I need in new solutions.
The upside is that I only have the projects in my workspace which I really need and it still changes in all other solutions.
The downside is that it changes in all other solutions too, means that if you change the API of a widely used library, you'll have to check all your other solutions if incompatibilities.

Should a Visual Studio project be contained in more than one solution?

Note: This is for a shop that works in C++, C++/CLI, and C# with some products being delivered as a combination of all three.
We currently have a rule that a project should have one and only one containing solution. The rule was originally instated because the source control plug-in for Visual Studio was unable to cope with projects that were contained in multiple solutions, always attempting to change the source control bindings when changing from one solution to another.
For other reasons, we are going to stop using the source control plug-in altogether (not dropping source control, just the brain-dead plug-in). It re-opens the question of whether or not to continue the policy of restricting projects to be contained in only one solution.
We have quite a bit of code in libraries, dlls, and assemblies that are consumed by multiple deliverable products, and we currently control this with a system of inter-solution dependency management whereby if one is working in the solution for an end-product, it is a simple matter to request a build of the dependency solutions, which kicks off other instances of Visual Studio to build them. The system works, but has the following drawbacks:
The solutions for the common projects are often too fat, containing a few projects needed by the product being currently developed and usually a lot more that aren't needed for the development work at hand. They have merely been lumped into a sort-of catch-all solution that covers projects that are merely loosely related. This results in extended build times due to the compilation of unneeded code.
Where we have tried to address the above fat solutions, we are often left with a too skinny solution that contains just one project. Each of these requires additional configuration in the inter-solution dependency management system. This, too, can increase build times as multiple instances of Visual Studio are spun up.
I am considering revising the policy to allow a project used in multiple deliverable products to be contained in more than one solution. We could eliminate the inter-solution dependency management and severely reduce the number of solutions (down to one per product). I am concerned about the amount of work this reorganization will take and whether or not it will be worth the effort. I'm afraid I won't even be able to detect the potential benefits until the team has been working with it for a while. I also foresee a couple of potential issues which are the true questions here.
Do a large number of projects in a single solution pose any stability problems in Visual Studio 2005 (our current development platform)? Does it get any better in VS 2008 or VS 2010?
If a project is contained in more than one solution, how can one manage the effects on the multiple solutions should project configurations be modified (such as adding a new configuration)?
To anyone already working in an environment with one solution per deliverable product, with common components as projects contained in multiple solutions: Have you encountered any significant drawbacks to such a configuration?
No, use as many solutions as is convenient.
For example, we have a large solution that builds about 53 projects. It includes an installer and uninstaller so that they can be conveniently built by our build server, but if I want to work on those applications, I load them in their own solutions (1 project each), rather than wasitng all that time loading 69 other unnecessary projects. They don't have any dependencies on the other projects, so there's no problem at all doing it this way (indeed, it's a lot more efficient as the solution loads and builds way faster)
The only caveat of multiple solutions is that you have to be careful in any case where you don't build a dependency (e.g. if you don't build a library, then you need to be careful that it gets built whenever the source code for it changes, because it will no longer be built automatically for you)
edit
To answer the last part of your question (because SO takes the question away while you're editing the answer!), the only problem with Solutions in VS2005 is that it is very slow with a lot of projects in them. VS2008 is much faster at loading a large solution, but the main hit is just that the more projects there are in a solution, the longer it takes to build (even if it is just skipping projects that don't need to be built, it takes a long time)
If you add a new solution configuration, then just make one uber-solution (or just keep your existing one!) and then make your changes in that so that they are applied to all porjects in one go. You will still have to add that new configuration to any separate solutions you want to use, but if they're one-project solutions you can just delete them, load up the .csproj and it'll be rebuilt automatically with all the configs in it. And adding new configurations probably isn't going to happen very often.
The main problems with having one project in several solutions are:
If you make a change in the project, it may cause a compile error in another solution in which it is used.
The solutions must constantly be updated to keep up with the changes in the common projects
The benefit of having a project in each solution that it is used is:
It is easier to debug when you can follow the problem done to the souce code.
Another way to do it would be to have each solution use the the dll's of the common projects that they require. Then each solution can decide when they want to change which version they use.
The number of projects in a solution is not a major problem. But it will make the sollution slower to load and build. We have solutions of over 50 projects.
I too work in an environment that has many common projects that are used in several deliverables. Our policy has been one solution per deliverable application. So a common project may be included in several solutions. This has worked well for us. The common projects, while contained in separate solutions, all map to the same source code repository locations. So if the common code is changed, all containing applications are affected. Our continuous integration system serves as a check that other applications do not break as a result of the change to the common code.
The more projects you have in a VS solution, the longer it takes to load and it just sounds complicated having to manage different build configurations and dependencies in a single solution.
We have a "master solution" that contains over 100 projects. This took forever to load in VS.2005 until Microsoft released Intellisense fixes described here.
Our automated "continuous integration" build procedure always builds the master solution. For development, I divide the "master solution" into smaller solutions that contain a subset of related projects. Maintaining this structure takes some time when new projects are added, but is well worth it.
The only problem I've discovered with projects in multiple solutions is avoided by using $(ProjectDir) instead of $(SolutionDir) in build rules, as the latter depends on how the project is loaded.
Tools for SLN file (Visual Studio Solution file) contains a tool that:
Make it possible to create filters for a SLN file. The way it work is
that when the filter file is opened, a temporary solution is created
dynamically. The created solution file contain only the projects that
are specified in the filter, and all the dependencies of those
projects. This make it possible to have a mega-solution that contain
all the projects needed to build the complete system but still have
the possibility to work efficiently on a subset of the system.
This removes a big part of the cost of maintain sub-set solution files for speed of development.
However you need to ask youself if you have more project files then you need, as combining project files can speed up compiles and loading of soltuions greatly.
There is now a free Visual Studio extension, "Funnel", that solves this problem by loading predefined subsets of the solution. The link is for VS2012-VS2015; there is also a VS2010 version referenced on the extension home page.
You can set up multiple profiles (i.e. project combinations). These are stored in a parallel solution.sln.vsext file and that file can be committed and shared with your team. While VS2015 has gotten much better at handling large, 100+ C/C++/C# project solutions, I find it particularly useful for excluding makefile projects that are built every time the solution is built.

how to generate multi part assembly ( per folder) in visual studio for custom library project , C#?

Is there a pre build action or some compiler switch that we can add?
I have just too many projects in our solution at the moment. I want to add new modules and compile them into separate assemblies.I am looking for options where I can avoid adding new projects for each assembly.
I am using Visual Studio 2005.
Also, It will be worthwhile to know if 2008 has better features over this space.
edit #1: There are two development teams working on this project and we want to cut the modules broadly into two verticals and keep the assemblies separate so that the ongoing patches ( post release ) do not overlap with the functionality in two verticals and also the testing footprint is minimized.
Currently the solution has about 8 projects and we need to setup the structure for the second team to start development.
I do not want to end up adding 5 or 6
new projects in the solution but
rather create folders in the existing
projects so separate code for the new
team or some easy way.
No, Visual Studio is still "one project per assembly". Do you really need to have that many different assemblies?
You may be able to write your own build rules which create multiple assemblies from a single project, but I suspect it's going to lead to a world of pain where Visual Studio gets very confused.
If you could give us more details about why you want lots of assemblies, we may be able to help you come up with a different solution.
EDIT: Having read your updated question, it sounds like you would possibly be better off just working off two branches in source control, and merging into the trunk (and updating from the trunk) appropriately. Alternatively, if the two teams really are working on independent parts of the code, maybe separate projects really is the best solution.
One of the problems (IMO) with Visual Studio is that the files in the projects are listed explicitly - which means that the project files become big merge bottlenecks. I prefer the Eclipse model where any source file under a source path is implicitly included in the build (unless you explicitly exclude it).
Neither Visual Studio 2005 nor 2008 lets you create multi-file assemblies. However, you can run the C# compiler at the command line with the '/addmodule:ModuleName' switch and it'll do what you want. For general details on command line usage of csc see this article. For description of the /addmodule switch see this one.
That said, however, you're most-likely taking a non-optimal approach here. In normal situations you should not have to want to create multi-file assemblies just because you have too many projects. Give more details of your general problem so that people can offer suggestions regarding that.
I'd heed the advice you've been given thus far--if you find yourself asking such questions, there's probably a deeper design issue that's being overlooked--but if you really must do what you're suggesting be done, you have several options. You can hack the project file to allow you to compile files into separate assemblies: the project file is an msbuild file, so there's a lot you can do with it. Also, you can simply use an msbuild file for building your projects and solutions. Or you can use a different build system entirely--NAnt is one example.
The likely problem with these suggestions is that they won't be feasible for your work environment. It's no good to start hacking away at project files that other people on your team use, or to just decide that this or that solution is going to be built using your custom msbuild file. There are many good reasons to use something like a single custom msbuild file, or NAnt, to build your projects, but it's always the wrong decision if it's not made with input from everyone the decision affects.

Resources