Great question and I look forward to reading the responses to this. Just wanted to thank you for asking this.
I personally am a fan of the n-tier architecture. When I start out I will typically create two projects for a web application, the first for the Business Logic and Database access, this is a class library project. Then I add a web application project for the actual website.
I have in the past built a data access framework that I use that leverages the Microsoft Data Application Block for all data access, and that is what I use to structure all data calls.
I have at times used codesmith or other items, but so far, I've found better luck, just rolling my own code, as I can get more granular with the data. Granted if I had time to research other ORM tools, I might not need to be concerned about it...
I find that the best approach is typically to create your business objects, data validation and all of the "business" pieces of the application. Then program in the data access pieces, and finish by putting everything together with the presentation code at the end. It takes some discipline to be able to do this, but it ensures that you are building things in a manner that can be re-used, and I have had great success.
The book you referenced might be a good example to start with as well.
Addition from comment
In response to a comment posted. Typically inside my Business/Data class library I will use namespaces to separate out the logic from the data. A few key things are done here.
My data method calls are all limited in scope to the assembly, they are NOT items that can be called directly, this way I enforce data access through the business logic for all presentation callers
All data input and output is done via objects, rather than DataSets or any other variant
The Business methods after validation will call specific methods from the data components to get the needed information.
I think each of the methods you have outlined has its merits and its downsides. Which you choose will be a matter of personal preference, the experiences of those in your team and the type of project - Linq2Sql is great to get up and running quickly but might not be best suited to a large and/or complex enterprise project for example.. the best thing you can do there is try a few and get to know them.
As for patterns, they help solve specific and recurring problems in a proven way. They also aid familiarisation for developers who didn't write the code. As above, it is worth trying a few to get a feel for what they do and when to use them - but they solutions to specific programming problems rather than architectural patterns.
My typical working process runs:
- Create a logical entity model
- Create the data storage for the entity model
- Create the data access code and business objects
- Create the logic / business layer
- Create the presentation layer
I would typically split Data Access and Business Objects, Business Logic and Presentation (web site / winforms) into their own projects, plus anything that I might want to re-use at a later date also goes in its own project. I also have a Base project containing common extensions and interfaces that I re-use in almost everything I do.
In terms of architecture, I try to ensure my projects are loosely coupled so that you can easily move from a three tier to n-tier architecture easily. Loose coupling also means that you can switch your backing store and all you need to do is write a new Data Access layer with all of your logic and presentation code remaining unchanged.
I think it's important not to get too hung up on three versus n tier - if you separate your concerns properly extending your system across multiple tiers at later date will not be a difficult exercise.
Such a broad (and good) question. Deep breath.
Not to take away from Design Patterns but they're the tactics compared to the strategy of architecture. Learn them of course, but that's not especially pertinent here.
A lot of the things you mention in the question are not mutually exclusive and could be thought of as sub-strategies for specific sections of the overall architecture. My personal preferences have changed enormously over time and with experience, and I'm still completely naive of some fascinating technology, but fwiw I think there's only one global constant of architecture:
Separation of concerns.
This principle is your "gold standard" I think, which informs so many good things: unit-testing, design by contract, dependency injection, MVC, n-tier. I say the first step is to understand SoC and the second is to act on it with test driven development. Everything else I think has pros and cons, but the benefits of maintenance, conception and an architecture driven by recognising the problems first is beyond doubt.
My bookmarks folder is not what I thought it was, but these are some of the online pieces which solidified my opinions on this matter:
Edit: where do you start with the blank canvas?
Add your unit test library of choice and sketch out the tests (aka facts).
Test > Design > Code > Goto 1
I wouldn't rule out ASP.NET MVC.
The release candidate is due out in January, and surprisingly this time Microsoft seems to be following the true meaning of RC and unless any show stopper bugs are found it will also be made the RTM version.