The World’s Leading Microsoft .NET Magazine
   
 
The .NET Addict's Blog

My Top Tags

                                                           

My RSS Feeds








Latest Diggs - Programming

Internet Blogs - Blog Top Sites

Site Hits

Total: 2,639,104
since: 19 Jan 2005

Exploring the MVC Pattern in WPF

posted Tue 10 Apr 07

In a previous article, I discussed how I felt that Interface Builder and Xcode were far more conducive to creating an application that conforms to the MVC pattern than Visual Studio 2005. The comment appeared that the code-behind for a particular view (e.g. the .xaml.cs file) was actually not the controller, but the view itself.

This makes sense from a technical standpoint, considering the .xaml file and the .xaml.cs file are both partial classes that combine to form a single class. So, if the code-behind is not the controller (an assertion I agree with completely), then where the hell is the controller?

I originally had a screenshot to show you, but my blog software is flaking out. Picture if you will, a screenshot of the Solution Explorer wherein you have three folders: Views, Models, and Controllers. I have placed App.xaml/App.xaml.cs in Controllers, I've placed a file called Customer.cs in the Models folder, and I've placed MainWindow.xaml/MainWindow.xaml.cs in the Views folder.

What does this get me? Not much at the moment. What it initially does is help remind the developer that the .cs partial portion of MainWindow is just that, a portion of the view class. As such, it should only do view-related things. In other words, if the view needs a method to transform something or trigger an animation, I fully expect that to be in the "code behind" (.xaml.cs) file. However, when you push a button on the view, the action taken should be taken by the controller.

In other words, you might have the following in your view:

InsertButton_Click(object sender, RoutedEventArgs e)
{
    _controller.InsertRow(param, param, param, param);
}

In Cocoa terms, the act of forwarding the button click event to the controller is taken care of when you control-drag from your button to your controller (Outlets and Actions are one of my favorite features of Cocoa, btw).

So, you've got your button rigged up, but... how did you get a reference to the controller stored in _controller ? The answer is that, in order to link the controller and the view without using code-behind/partial classes, we need to instantiate the controller from inside the view's constructor:

public MainWindow()
{
    InitializeComponent();
    _controller = new MainWindowController(this);
}

After this point, the controller and the view can communicate through properly exposed public properties and methods. What I don't like about this implementation is:

  • I have to manually create the link between the view and the controller, it isn't something of which VS 2005 is intrinsically aware
  • Each time I want the controller to do something in response to a UI event, I need to write a line (or more) of code in order to trap the GUI information and pass it along to the controller
  • The view and the controller are tightly bound. Some argue this is a good thing, some argue it isn't. I say it doesn't "feel right".

What I do like about this implementation:

  • The controller is testable through automation code
  • The view is testable through automation code

If any of you have built MVC or MVP pattern implementations in WPF, please post a comment here. I'm sure that I'm missing something. The .NET Framework is an extremely flexible platform, and given enough time and resources, I'm sure someone could have abstracted a layer inside WPF apps that properly emulates MVC. My analysis in this blog post was based purely on what you get "out of the box" without doing much extra work.

tags:                      

links: digg this    del.icio.us    technorati    reddit




1. Kevin Hoffman left...
Tue 10 Apr 07 7:44 am

One possibility to increase flexibility here would be to make it so that the controller expects an instance of a particular Interface rather than a concrete class. This would allow a controller to operate on more than one view, and potentially make it more re-usable or more testable. Admittedly I've never used that in a production app, so I don't know how practical it is.


2. Jordan Vinarub left...
Tue 10 Apr 07 8:06 am

If you leverage Dependency Injection or the Inversion of Control pattern, you would inject the controller into the view from an outside factory. You can leverage an interface if you want, but the main point is that the view delegates to the model for operations. How it gets that reference to the model is external to the view itself. This is the foundation for something like the Spring Framework.

Does this help?


3. Kevin Hoffman left...
Tue 10 Apr 07 8:09 am

It totally helps, but also helps me make my point - I can't do a really good job of implementing MVC unless I use some other framework on top of .NET like Spring, which lets me visually inject stuff like the linkage between view and controller. While it lets me not have to see the code that makes that link, it also means I am still without a decent "out of the box" way of implementing MVC in WPF.


4. keith left...
Tue 10 Apr 07 10:21 am :: http://www.afex2win.com

absolutely. .net was not geared towards MVC like other frameworks such as rails et al. it is one of the biggest complaints of ASP.NET developers. webforms are horrible for testability, which is why alot of new development is looking towards things like MonoRail and the like.

using an interface to the view allows for a decoupling from the controller, and does work well in production, but this whole issue is one the reasons why IoC/DJ systems exist. now whether or not the view knows about the concrete controller is a whole different discussion. the most decoupled solution i know of is controller acting through an interface to trigger view actions, and the view raising events through that interface which the controller is listening for


5. James Gregurich left...
Tue 10 Apr 07 10:43 am

There was a post on this blog yesterday that basically said MVC was a waste of time if it wasn't about automated testing of controllers. Comments today about MVC focus on automated testing.

I must wholeheartedly disagree with the sentiment that MVC is primarily about automated testing. MVC is primarily about keeping your design modular and therefore keeping it extensible and maintainable. Automated testability is just a nice side-effect.


6. Kevin Hoffman left...
Tue 10 Apr 07 10:51 am

"There was a post on this blog yesterday that basically said MVC was a waste of time if it wasn't about automated testing of controllers" I don't know whose blog you're reading, but I personally don't think MVC has anything to do with automated testability. It's a damn fine side effect, but the real benefit of MVC implementations are in the architecture, the re-use, the maintainability, the scalability..and it just works really well. As you said, getting testability out of MVC is a nice side effect.

I've never once claimed that testability is a goal of MVC.


7. James Gregurich left...
Tue 10 Apr 07 1:18 pm

Kevin,

wasn't you that said it. it was a commenter.

here is the actual quote:

"controllers should be implemented as seperate classes so that they are testable independent of the view. if you cant test them alone, doing any MVC-like pattern is a waste of time. "


8. Kevin Hoffman left...
Tue 10 Apr 07 1:21 pm

Ah yes, well.. standard rule of blogging applies here: The opinions of people who comment on my blog posts are not necessarily my own. I am in your camp - testability is a nice secondary effect of properly separated MVC, but getting a really good MVC going provides the developer with other more important benefits above and beyond testability.


9. keith left...
Tue 10 Apr 07 4:34 pm :: http://www.afex2win.com

"I must wholeheartedly disagree with the sentiment that MVC is primarily about automated testing. MVC is primarily about keeping your design modular and therefore keeping it extensible and maintainable. Automated testability is just a nice side-effect"

Test driven development maintains the opposite approach. by designing for testability, having modular, extensible, easily maintainable code is the side effect, MVC or not. obviously, TDD and MVC are not mutually inclusive, but i for one would not voluntarily work on a project that did not hold automated tests in high regard.


10. James Gregurich left...
Tue 10 Apr 07 5:49 pm

" but i for one would not voluntarily work on a project that did not hold automated tests in high regard."

Kieth, if I may be nosey, what are the sizes of the companies (in terms of developers and QA people) that you have worked at that focus heavily on writing automated testing code?


11. keith left...
Tue 10 Apr 07 7:20 pm :: http://www.afex2win.com

sure, no problem. i would describe it as large. my current client is making enterprise-scale software. and my consulting company employs 2000 developers nationwide.


12. Kevin Hoffman left...
Tue 10 Apr 07 9:07 pm

I'm also a fan of TDD. I think situationally, it becomes useful. For my home hobby-use (which is the development I'm currently doing with the Mac), I don't need to worry about TDD. But, if I was working on production-quality stuff for a mission critical application, you can bet that I'd want a really good MVC separation and testability of my controllers and my models and my views.


13. James Gregurich left...
Wed 11 Apr 07 12:51 am

keith,

As I thought...large shops have the drone level staffing necessary to do that sort of thing. small shops do not.

Also, enterprise level shops do systems that span multiple machines and serve perhaps millions of people and a malfunction means millions of dollars may be lost. So, automated testing has a real benefit in your world.

The small shop selling desktop software is more interested in getting new features out the door to keep up the revenue stream. A price paid for optimizing for new feature development is that quality control is much more lax.

So, if you ever go to work for a small development shop, don't be shocked when they don't have automated testing and teams of QA people in cubicles.

-James


14. jdn left...
Wed 11 Apr 07 9:04 pm :: http://www.e-Crescendo.com

Have you taken a look at this?:

http://haacked.com/archive/2006/08/09/ASP.NETSupervisingControllerModelView PresenterFromSchematicToUnitTestsToCode.aspx

I don't see why you couldn't use this for WPF, and get the sort of separation you want (I'm using a modified version of it for ASP.NET, but no reason why it wouldn't work for WPF that I can see).


15. keith left...
Thu 12 Apr 07 12:09 am :: http://www.afex2win.com

james:

drone level staffing? i'm not sure whether to be offended or not. you obviously dont understand TDD and/or agile. quality is the responsibility of the DEVELOPERS, not "QA people in cubicles". the entire point of incremental development is to be able to always have production quality software so you can more quickly, and safely, add features to "keep up the revenue stream" without introducing bugs.

this mindset CAME from small shops (obviously not yours) and only now is creeping into the enterprise, the land of BDUF.

any software company (big or small) putting extra features ahead of quality is just being irresponsible. and if your response would be "but our software has high quality" my question to you is can you prove it? i can by pressing the "run tests" button.


16. James Gregurich left...
Thu 12 Apr 07 12:36 am

keith,

What would be possible be offended by in my comments?

I've worked in Corporate IT. I've worked as a consultant to corporations. I know how the system works.

I have no idea what "TDD" or "Agile" is...and am not interested in finding out right now. I'm up to my armpits in learning the science of color space transformations and revamping the I/O system in our legacy C application to improve its performance. I don't have time to write automated test code. My company makes money when I ship that feature to calculate the ink density that a Quark or InDesign document will produce when it is printed on a press....we make no money by putting a bullet point on the box talking about the great automated test system we have in place.

I maintain the quality of my code by following proper design fundamentals religiously. I manage my memory with smart pointers. I trace through my execution paths ensuring exception safety. I encapsulate my data and insulate software components from one another.

Do I make mistakes? sure...but because of the nature of the apps we develop, those mistakes are rooted out pretty quickly by a single human running a battery of tests over a few hours.

I'm not saying automated testing is a bad thing...if it works for you, do it to your heart's delight. But not every development shop has your set of requirements or goals.

I also maintain my original statement, MVC is about proper design of a system...not automated testing.


17. keith left...
Thu 12 Apr 07 3:01 pm :: http://www.afex2win.com

then i encourage you to look into those topics.

"I don't have time to write automated test code" but you have time to spend hours and hours manually testing your software each day/week/month? you only have to write a test once, but you have to manually test the same feature each time you test by hand.

you seem to think automated testing is hard, or a lot of work. IMO, the opposite is true. NOT having automated testing is hard b/c in that evironment, bugs can be re-introduced after somebody thought they had fixed it, you aren't sure at any one moment what works and what doesn't, bugs usually show themselves in areas not actually broken (wild goose chase syndrome), and testing literally takes hours (as you have said)

imagine if those hours spent manually testing where instead spent developing new features? you sure could make alot more money that way. automated unit and integration tests save you time and make things easier, not the other way around.

of course, retro-fitting an existing legacy app for testing will probably be more work than its worth since software not designed for testability will not be able to benefit from unit and integration level testing.


18. James Gregurich left...
Thu 12 Apr 07 5:02 pm

keith,

I don't do the primary testing. we have QA people for that. I do basic testing to make sure my changes work right then pass it on to QA to do more comprehensive testing.

The QA guys are not a developers. they don't write code.

We don't have problems with reintroducing bugs because we are a small team and we use version control as well as a bug tracking system.

If this was a team of 20 guys, we might need a tool like that, but for a handful of people, it is overkill.

All we really need for testing an app or our app's nature is a solid suite of test data to drive through it and observe the results. By the nature of our business model, we don't have to be perfect the first time. We can have minor problems and fix them over time. What we do isn't mission criticial and if it fails then at worst a customer has to wait a couple of weeks for a bug fix release.

Your business is likely entirely different. One little screw up deployed on a production system can cost a company a ton of money and repairing the damage can be very costly. I used to work for a large retail company of about 90,000 employees. the code that drives the cash registers and credit card machines in a store has to be carefully scrutinized. A screwup in that can take an entire store offline during the christmas rush or push bad data up to the corporate mainframe and screw up the accounting department...not a good thing. So in that circumstance, rigorous QA policies and practices pay off.

But for a little mom and pop operation like I work at these days, it won't create a significant return on investment of engineering time.

I'm not saying those topics are without merit...I am just saying I personally have far bigger fish to fry before I need to worry about automated testing.


19. Sebastien Lambla left...
Fri 19 Oct 07 5:03 pm :: http://serialseb.blogspot.com

I have to say I usually use a ViewModel / View approach, where the ViewModel is simply an object within your view, defined as a resource within your XAML page. Just like the presenter pattern in asp.net, the idea is to write modelling code the xaml page binds to, and let the code execute in reaction to logical commands from the view. The cleaner and more wpf like you write your model wrappers, the better the separation, to the point where your xaml page / control and your viewmodel know nothing about each others, and only leverage the model and commands. This is inherently extremely testable.


Tag Related Posts

So I'm in the LA Times ;)

Wed 27 Aug 08 2:51 P GMT-05
tags:                  

MobileMe vs. Live Mesh Throwdown - Round 1

Wed 16 Jul 08 10:33 A GMT-05

Building Model Classes in C# and Cocoa

Sun 15 Jun 08 3:13 P GMT-05
tags:            

MobileMe vs. Live Mesh - Round 1

Wed 11 Jun 08 12:20 A GMT-05

My Macbook Air is masculine, dammit!

Mon 17 Mar 08 6:59 P GMT-05
tags:          

My Macbook Air Review

Sun 02 Mar 08 4:20 P GMT-05

Video of the Macbook Air in Action

Wed 20 Feb 08 3:04 P GMT-05

Scott Guthrie Updates the ASP.NET MVC Roadmap

Wed 13 Feb 08 3:49 P GMT-05
tags:    

CLINQ v1 Demo - Network Message Filtering

Wed 09 Jan 08 7:47 P GMT-05
tags:        

ASP.NET 3.5 Extensions Preview Released

Mon 10 Dec 07 2:10 P GMT-05

Leopard Code Sample : Sprinkling in some Bonjour

Tue 27 Nov 07 2:32 P GMT-05
tags:        

Leopard Sample: A Bound NSCollectionView

Mon 29 Oct 07 1:41 A GMT-05

Leopard is out - let the code samples begin!

Fri 26 Oct 07 10:09 A GMT-05
tags:          

My life is complete : iPhone SDK is CONFIRMED.

Wed 17 Oct 07 6:38 P GMT-05
tags:          

Leopard Shipping October 26th!!

Tue 16 Oct 07 4:59 P GMT-05
tags:        

Microsoft unveils an MVC framework for ASP.NET

Mon 08 Oct 07 12:58 P GMT-05
tags:      

Building a Ledger Style for WPF Grids

Tue 21 Aug 07 3:30 P GMT-05
tags:    

My iPhone Review

Mon 23 Jul 07 1:09 P GMT-05
tags:        

Microsoft Codename Acropolis - Unwrapped

Wed 20 Jun 07 3:22 P GMT-05
tags:              

The dreaded language bleed-over has begun

Tue 19 Jun 07 6:23 P GMT-05
tags:        

My first "Acropolis" Application

Mon 04 Jun 07 1:40 P GMT-05
tags:      

Exploring the Delegate Design Pattern

Mon 14 May 07 6:30 P GMT-05

Core Data - Almost too Easy?

Wed 18 Apr 07 2:23 P GMT-05

Will Silverlight be DOA?

Mon 16 Apr 07 8:02 P GMT-05

Exploring the MVC Pattern in WPF

Tue 10 Apr 07 12:51 P GMT-05
tags: