Fog Creek Software
Discussion Board




Welcome! and rules

Joel on Software

ASP.NET presentation/business/data layer

I've been working with ASP.NET for several months now, but I'm a little uncomfortable with managing the separation between the business, data and presentation layers.

It *seems* like there's a clear divide between the .aspx page design (presentation), code behind (business logic) and data layers (data adapters & data sets). However, there's quite a bit of 'leakage' between all three layers.

For instance, the validators are in the page design, and manipulation of the interface is done in the code behind part.

What's the best way to keep everything as separate as possible?

Colm O'Connor
Friday, April 22, 2005

I don't there is a "best" way, but there are options. MSDN lists a few here:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpatterns/html/EspWebPresentationPatterns.asp?frame=true

Personally, I have found that using the standard ASP.NET data binding model makes it difficult to write good code. "Leaks" spring out all over the place and eventually the dam breaks.

Two pieces of advice:

1) You don't have to use the same model in every page. I have a lot of web apps that use MVC , PageController, _and_ FrontController.

2) Don't get caught up in the patterns. Do the simplest thing that works and make sure it is maintainable in the long run.

Jeff Mastry
Friday, April 22, 2005

I agree with Jeff to so the simplest thing.

Most of the time, for simple apps, I have the following:

An aspx with the markup and script

An aspx.cs with presentation logic (not business logic)

A 'logic' namespace containing classes to perform whatever it is the app does. The presentation logic tells the logic class what to do.

A 'data' namespace containing classes to serve data to the logic classes.

I find this provides organization without too much overhead. For simple apps, sometimes patterns are overkill.

Rick Childress (intellithought, inc.)
Friday, April 22, 2005

Hi, Colm.

Lower levels are expected to have no knowledge of higher ones, so it looks like you really have only 2 layers in your design: you keep business logic and presentation (code behind) together. This layer model, I believe, works best for smaller teams and applications in terms of development time (and probably maintenance as well).

In bigger teams/apps (and especially when UI and BL are developed by different teams) I find myself using the separation Rick described. Plus, business entities (typed datasets or classes for domain object) go to separate namespace.

namespace Product.Domain
  Holds domain object data structure, object-level logic.

namespace Product.DataAccess
  Holds DB communication code, ORM.
  Uses Product.Domain.

namespace Product.BL
  Holds business logic.
  Uses Product.DataAccess, Product.Domain.

namespace Product.Test
  Does BL unit testing.
  Uses Product.BL, Product.Domain.

namespace Product.UI
  Holds presentaion logic.
  Uses Product.BL, Product.Domain.

In some cases it makes sense to introduce even more layers to keep big projects well organized or satisfy business requirements. Downside of it is that some logic (probably, the worst example is validation) becomes scattered and to some extent duplicated on multiple layers.

May I suggest a book, that Jeff Mastry recommends here:
http://discuss.fogcreek.com/dotnetquestions/default.asp?cmd=show&ixPost=5988&ixReplies=2
It covers multi-layer architecture very well, it is nicely written and... and I just love it ;) (thanks a lot, Jeff, for the reference)

DK
Friday, April 22, 2005

The CodeBehind shouldn't be your business layer but the UI Controller (as in MVC).

Business objects (entities and process) should be put in separate classes from the page classes.

And I second the suggestion of reading the Microsoft Patterns and Practices. Specialy the topic on 'Designing Applications and Services', it gives some heuristics for assigning responsabilities to classes in the context of a three-layered app.

.NET Developer
Friday, April 22, 2005

This is a decision you need to take depending on the size/complexity of your project. If the project is small and there isn't much of "business layer" as such - you would probably mix presentation and business processing within the code-behind.

But a cleaner way is to create different classes for the business objects, expose them as API's for the code-behind to use. With some thinking, it is quite possible to make it clean so that the code behind focuses on "how to display" and the backend classes deal with the rest. A good way to go about it is

-Bus. Layers must provide API's only for the primitive values (i.e. values that have no UI attributes, but on which processing logic is based)

-code-behind should validate params, and pass them to the bus. API's.

-Bus. layers should only return primitive values and let the code-behind figure out how to render it.


You should take a look at the Microsoft Enterprise Library layers, it will simplify many of the "usual" things you do as part of design.

v
Saturday, April 23, 2005

>The CodeBehind shouldn't be your business layer
>but the UI Controller (as in MVC).

I'm starting to come around to this point.

>Business objects (entities and process) should be
>put in separate classes from the page classes.

If the logic is complex then it makes much more sense to put it in a class, yes. I think if the logic is simple, though, creating new classes for it adds unnecessary complexity.

Perhaps pragmatically speaking, a little leakage is necessary.

Colm O'Connor
Tuesday, April 26, 2005

*  Recent Topics

*  Fog Creek Home