views:

70

answers:

2

I am writing a Windows Forms application which is growing and becoming quite extensive.

Initially I thought that a separate project for graphical components and one for business logic and one for data access would be the best approach.

As the application gets larger I'm beginning to think that a more modular approach would be cleaner... e.g. a project containing user controls, business logic and data access for each 'category' of data.

For example... DAL objects relating to Products along with the associated business objects and user controls in a single project. This should end up with a larger number of projects within the solution, each one being self contained.

This may, however, cause more complications as the data is often linked (product table is linked with supplier table and orders table and parts list table etc.) So it would be difficult to completely abstract each category.

There are hundreds of software architecture articles online but not many which help you to translate that architecture into solutions, projects and code.

Could anyone point me in the right direction?

+3  A: 

I would keep UI, data and business layers in separate projects. This essentially reduces chance of tight coupling - for example, data layer being directly used by UI code etc. Now, if you wish to divide this vertically then you can do that as well as i.e. Products will have three projects UI, Business & Dal and so on. There can be multiple considerations out here:

  1. Why are you separating vertically - do you see a possible independent reuse? If no then avoid dividing.
  2. If you must divide then you may choose divide say only UI layer from management perspective because it may have lot of code
  3. Or you may divide all layers but at coarse grain. For example, Products and also its children together.

As far as cross category references are concerned, they cannot be avoided but they must be done via well documented & designed contract. For example, Orders UI may call Products BL to get list of products (note that the same method will be used by many other UI components for similar functionality).

VinayC
A: 

VinayC is on to it, here's some extras that augment his answer (too hard in a comment).

  • Abstract out all data access behind interfaces, that way you can swap different ones in and out, and you won't have so many dependencies hard-wired into the rest of the app.
  • When you design these interfaces you'll be able to apply some of your "vertical" thinking. See: Interface Segregation Principle and Stable Abstractions Principle as a start.
  • I'd make a seperate assembly (and project) for each layer, plus a "Common" assembly for constants etc. Keep this as free of dependencies as possible.
  • Where I've used this approach, I've sometimes put my POCO's in a folder in the common assembly so they can be easily re-used. The interfaces I use to seperate the BL and DAL use these, and I sometimes re-use them between other layers as well.
  • Consider using attributes; they can provide you with a really useful extensibility point.
  • Put commonly used controls into control libraries for easy re-use.
  • Don't try to seperate out parts of a domain model / data model (e.g: order and parts) that are tightly bound to each other in a business sense.
Adrian K