C# – GUI, BLL, DAL Organization in a Project

ccode-organizationlayers

I'm reading about application layers, and want to use this design in my next project (c#, .Net). Some questions:

  1. Is the separation of layers done through namespaces? Project.BLL.Whatever, Project.DAL.Whatever

  2. Is it more appropriate to separate by layers, then components (Project.BLL.Component1), or by components, then layers (Project.Component1.BLL)

  3. For my DAL, is this layer further organized using different classes? If all database calls are put into a single class, there is no organization. Would it be better to split these up with different classes or namespaces?

  4. Are DAL classes typically static? It seems cumbersome to instantiate a DAL object before calling one of its methods each time.

Any other tips for doing things the correct way with these layers would be appreciated.

Best Answer

  1. Yes. And also assemblies.
  2. I'd separate by layers, then components.
  3. Yes. There are different approaches to this, but I'd have an IDatabaseService (abstracting the various manners in which the database is called -- this can almost be a direct mapping of the ExecuteScalar/ExecuteNonQuery/ExecuteReader), and then various data access classes that partition by type of data. For example, you could have a UserDataAccess class that would have simple CRUD methods that create/modify/delete User objects. Another approach would be to have a User object that has the CRUD built right in.
  4. No. That makes it much harder to unit test. You should use dependency injection to pass in dependencies to the constructor of each data access class (such as an IDatabaseService). You would then pass the data access objects into the business objects, like this:

    BusinessObject businessObject = new BusinessObject(new DataAccessObject(new DatabaseService())); businessObject.PerformOperation();

Each business object may need multiple data access objects. Your GUI code would also use one or more business objects. Some business objects may not need any data access objects but should never use the IDatabaseService directly.