views:

449

answers:

5

I have started a WinForms project a few weeks ago and as I did not really know what features I wanted, I just added them along the way. This now caused a horrible mess where my MainForm is a big ball of mud and where for example some important state changes are triggered by UI elements to the point I have to call the OnChange Event of a Control in order to change some state in the database.

In short: I've just started a new project where I want to take a better approach. I just don't know which would be the "good" one. In ASP.net MVC, I found the MVVM Pattern really useful, but on the Desktop, MVVM seems to be only intended for WPF, not for WinForms.

The other approach is a three-tier-architecture: I have my Database-Class which currently talks directly to the UI. I now create a new Static Class ("ApplicationState") that talks to the database and fires events to tell the UI "Hey, Something changed!". The UI would manipulate the State which will then handle the database persistence and again raise Events if the UI needs updating. The point here is that the ApplicationState class never modifies the UI directly, but that the UI subscribes to Events. That looks like a clean/"MVC-y" way of doing it, but maybe I am overlooking something here?

Basically my ultimate goal would be to have the UI completely independent from the database layer just to make sure I don't wire in business logic into the UI again.

+3  A: 

What I would always go for (first) is to have a layered application

  • Presentation Layer (JUST UI and databinding logic)
  • Interface Layer to the Business Layer (defining the contracts for accessing the BL)
  • Business Layer implementation (the actual logic, data validation etc...)
  • Interface Layer to the Data Access Layer (defining the contracts for accessing the DAL)
  • Data Access Layer implementation

This organizes your application extremely well. Then I'd look for some MVC kind approach. I did not develop so much with WinForms, more with Asp.net and some Java Desktop clients (where I used MVC). WinForms works more with the .Net databinding approach (DataSource, DataMember,...). You should go for that approach instead of trying to force something other. I found that it doesn't match that well.

What's always useful is to lay out our UI logic into different controls (like UserControls in Asp.net). This facilitates reuse.

Juri
You like lasagna, huh?
MusiGenesis
I guess that makes .NET the cheese between the layers?
Paul Williams
Where does the cheese layer fit into it? I like cheese.
Charlie Salts
@Paul - We have cheese on the brain, eh?
Charlie Salts
The cheese are the interface layers that keep the main things together and the dependency injection provided by MS Unity which gets the correct instantiations of the BL's etc.. :)
Juri
I think that approach makes sense for "big" applications, so +1. I just fear that for my application that is overkill. It's a simple application with 1 Main Form, 1 Database and 3 or 4 Additional Forms that do not do much. So 5 Layers may be really overkill, I'm more looking at the easiest way to exchange data between the UI and database without having all the business logic in the UI, and I do not know if a Static Class would be the way to go.
Michael Stum
@Michael: Well then I'd try to really separate it with an MVC approach, much like the one I linked in my post (although it's in Java you could easily "reprogram" it). Your controller could then be a singleton class that does the "domain + business logic".
Juri
+2  A: 

Just start writing unit-tests for everything you can think of. As some pieces will turnout difficult to unit-test because of tight coupling to the WinForms, separate them out. Clean. Wash. Repeat.

zvolkov
-1 because this is basically how he got to a big ball of mud in the first place, only without the unit tests.
MusiGenesis
@MusiGenesis, "only without the unit tests" -- that's a hell of a difference. The absence of unit-tests is what drives the big ball of mud.
zvolkov
Unit tests are no magic bullet, in my experience. Balls of mud result from adding stuff as you go, without a clear plan ahead of time. A ball of mud with an attached suite of tests is still a ball of mud (and sometimes the tests are another ball of mud).
MusiGenesis
Alright. You have 13k rep so you win :) Although a ball of mud with a plan is still a ball of mud.
zvolkov
I disagree in that it shouldn't be the sole approach to a well structured solution. I agree in that unit testing does result in well structured code. If yours does not, than you're not unit testing right.
Sergey
Unit Tests are one way of doing it, because that more or less forces me to move actual code out of Event-Handlers into classes, so there is some good truth about it.
Michael Stum
@Michael: ok, you have a 23K rep so you win. :)
MusiGenesis
+1 I'm researching the same concerns as the original asker and this answer is the only one that does not box you into a complex architectural pattern before you've even begun. This simple answer indicates that my *process* for developing web apps should carry over well to desktop apps. Thanks for the reassurance.
gWiz
+2  A: 

Don't throw in the towel on MVVM - it's valid for WinForms as well. Basically, if you use data-binding, you have to make a decision about what your objects will bind to. Often, especially for more complex UI, you dont want to bind directly to your domain objects, you want to build specialized classes (sometimes wrappers) that your UI can bind to which provide everything the view needs (the essence of MVVM) and the technique works just as well with Winforms.

A good series on WinForms Model-View-Presenter approach can be found at

The Build Your Own CAB Series Table of Contents

HokieMike
That article Series is really good, seems to be what I want.
Michael Stum
A: 

Our rule of thumb is to lean towards MVC for most websites due to the stateless nature of the web. Unless you're trying to provide a very rich web experience and bring in silverlight, then you should go with MVVM. XAML goes hand to hand with MVVM and can be your smart client choice as well (or a nice MVCP pattern).

True MVC is almost impossible to uphold in any other circumstance due to the fact that controllers are suppose to handle all input. Most non web architecture has controls that will provide this for you. In fact, most say that ASP.NET MVC is a hybrid MVC anyways but it's very good in my experience.

RailRhoad
+2  A: 

NDepend documentation comes with some pretty cool and advanced online blog posts, articles and white books concerning architecture of .NET code.

Advices on partitioning code through .NET assemblies

Control Components Dependencies to gain Clean Architecture

Re-factoring, Re-Structuring and the cost of Levelizing

Evolutionary Design and Acyclic componentization

Layering, the Level metric and the Discourse of Method

Fighting Fabricated Complexity

Also, if you want to continuously check that your UI code is independent from your database code, you can write easily some Code Query Language rules that will be checked live at development time in Visual Studio:

Keep your code structure clean

Patrick Smacchia - NDepend dev