I want all my layers BLL,DAL and UI to share classes (concrete or
interfaces).
It depends on what type of classes. If you need them all to access common domain entities, then sure.
The important part is what you allow those layers to do with those classes. Your client/UI layer shouldn't be able to modify the domain entities (and persist them) without going through some centralized business logic. This means your DAL shouldn't be accessible by your UI, although they can both share common entities, interfaces, etc...
A common approach is something like this:
UI -> BLL -> DAL -> Persistence storage (DB, file, etc...)
Each of those layers can access commmon classes. As long the UI can't directly access the DAL, you should be okay. You have a couple of options for this:
- Make the BLL accessible through a service (WCF, etc...)
- Put the DAL and BLL in the same project and make the DAL internal so only the BLL can access it
You end up with something like:
UI -> Service -> BLL -> DAL -> Persistence storage (DB, file, etc...)
I would strongly recommend Patterns of Enterprise Application Architecture by Martin Fowler. It will provide you with a good foundation for layering your application.
I prefer not to return datatables from my DAL methods but instead to
return objects that BLL can use directly.
That's a good idea. This is where the idea of ORM comes into play. The DAL will typically know how to talk to the DB, and the DAL will also know how to convert DB-specific structures into your domain model. Domain entities go into, and back out of, the DAL. Within the DAL, domain entities are converted to DB-specific structures when persisting data. And the reverse happens: when the BLL requests data, the DAL retrieves the data and converts it to domain enties before passing it back out.