Wednesday, April 16, 2008

Visual Studio project structure for large web applications


Having functionality encapsulated within .net dll projects is a vital part of any web application, and I recommend starting all new web applications with this in mind. The project structure we use in Zignals is:

Framework.dll :
This stores all the low level classes and functions that will be common to all web projects. For example, our framework has:

Session.cs: Handles all web application Session logic
Logging.cs: Handles all error and information logging
SqlWrapper: Handles all low-level interaction with the database
ZUtilities: All utility functions
Security: All encryption & security functions

Basically anything that is project independent. If you are building just one large web application (as in our case), you could have your business logic in this dll to save hassle with multiple references/namespaces, but if you want to re-use your common functions across multiple sites you should have a separate project for the business logic.

Holds all the functionality common among the various Visual Studio projects that are build for the current website. Having your business logic here allows developers of different project types (e.g. windows services, web services, web applications) use the same underlying business logic. In our case for example, we allow a user to Simulate an investment strategy online (web application). We also have a complex algorithm that automatically builds a strategy. Because of processing requirements, this algorithm runs as part of a windows service that allows processing to queue while waiting for a free CPU. Once the strategy is auto-built, it also needs to be simulated over a historical time period to assess performance. Since we have the “SimulateStrategy” function in the Strategy class in the BusinessLogic.dll, both the Windows Service project and the Web Application project can simple reference the BusinessLogic.dll project output and always use the most up-to-date version.

This project holds any ASCX files that we use. The reason for having these in a separate project is so we can have developers building controls independently of the developer consuming them. It also means that we can re-use these controls across multiple web projects. It also allows us to dynamically add these controls from cs code. For a detailed look at creating User Control Libraries, see

We have a custom controls project for any custom objects that we want to be able to store in the database (e.g. serialized into our DB cache). The reason for a separate project and solution is because of the fact that recompilation of a dll will create a different signature for the object and you won’t be able to deserialise objects stored in the database after re-compilation. Since you re-compile your web projects for every new line of code, this would make serializing and storing objects in the database impossible, hence the CustomControls library. Incidentally, we generally only have very basic objects in this library so there is very little call for recompilation.

WebApplication 1:
Whatever web application you would normally have produced.

Web Application 2:
If required. We have multiple web applications because of the division of labour (e.g. different developers or development teams can have “autonomous” responsibility for their own project), and because having hundreds of aspx files or directories in one project is cumbersome.

All these projects can be opened as part of one visual studio solution and you can set a build order that makes the framework compile first, then the business logic, and so on all the way up to the web applications.

In the example opposite, taken from our main VS solution, you can see the Framework and BusinessLogic projects and the 2 web projects (Dashboard and ZignalsTools).

The CustomWebControls project is called WidgetControls for our site.

You will also need to copy all the .ascx files for the CustomWebControls project into a directory of which ever web applications are using them. This is done by setting the pre-build event of the web project consuming the CustomWebControls to something like:

copy $(SolutionDir)\CustomWebControls\*.ascx $(ProjectDir)\UserControls\

You will also want to make sure that each project higher up the chain has a reference to the project output of the projects lower in the chain. E.g. BusinessLogic.dll has a reference to the project output of Framework.dll. This is done by right-clicking on “Add Reference” in the business logic project and selecting the “Projects” tab in the dialog box and selecting the relevant project.

Visual Studio will automatically organise the project build order based on the project references within the solution, so you shouldn't need to do anything else to get the projects to build correctly.

Scott Tattersall is lead developer of stock alerts, stock charts, and market sentiment for Zignals