Saturday, January 31, 2015

Is Test Driven Development Dead?

While catching up on some blog reading over the holidays, I ran across this interesting conversation between Kent Beck, Martin Fowler & David Heinemeier regarding TDD.  I soon found myself watching several hours of Google Hangouts soaking in the wisdom.

After watching it, all I have to say is that I still see TDD as a very valuable tool.  I try to use it when I can, but there are times I can't get it to fit certain situations.  I don't agree with the concept of test induced design damage.  I'd have to say that every time I've written a test for a portion of code, it has caused me to think about the design and most of the time I learn something I didn't know before.

Kent posted an interesting response on Facebook. Worth the read :)

Saturday, January 24, 2015

Using INotifyDataErrorInfo & Data Annotations [Required] Attribute in WPF on Objects

INotifyDataErrorInfo in combination with Data Annotations works great for error validation in WPF when using .NET 4.5.  A typically example of data annotations shows them being used on properties with primitive types such as integer or string.  When binding in WPF, one would bind a control such as a text box directly to the primitive property.  Error validation would occur on that binding.

     public string Name  
       get { return _name; }  
       set { SetProperty(ref _name, value); }  

      <TextBlock Text="{Binding Name}"/>  

Recently, I was working with some code that had a [Required] attribute on an object.  In the view-model the binding was to a nested property on that object. 

     public MaterialModel LinerMaterial  
       get { return _linerMaterial; }  
       set { SetProperty(ref _linerMaterial, value); }  

    <TextBlock Text="{Binding LinerMaterial.Name}"/>  

Validation was not working!  Validation attributes only work directly against the object to which they are applied.  I could have created a separate primitive property "MaterialName" and set that when a material was selected on the view model.  However, I decided to go with a slightly different solution.  I wrapped my text block with a stack panel, setting the data context of the stack panel to the MaterialModel object.

 <TextBlock HorizontalAlignment="Left" Text="Liner Material:"/>  
 <StackPanel DataContext="{Binding LinerMaterial}">  
      <TextBlock Text="{Binding .Name}"/>  

  Doing this causes validation to be raised on the stack panel, instead of the TextBlock.  
Error validation of the object showing on the stack panel
This could be considered a bit of a hack, but on the view model I was working on, it saved me from having to add three extra properties for primitives, and additional logic.  Also, I feel it conveys the intent better.  The view model doesn't require a material name, it requires a material.

Friday, January 16, 2015

Entity Framework - Configurable Database Connection String in ClickOnce Applications

On a recent project, I used Web API 2 and OWIN self hosting along with Entity Framework and LocalDb to allow our web-service to run on a local machine.  When the application was conceived, it was designed to run with LocalDb.  As the application evolved, it was asked if it could be connected to a shared database.

The architecture looks something like this: 

 WPF Shell
  >> OWIN SelfHost WebAPI2
        >>WebAPI2 Controller Project
             >>Entity Framework 6 DAL

Entity Framework code first has several methods of getting a connection string for the DbContext to use. 
  • Connection by convention
    • Uses the DbContext name to create the database
  • Connection by convention with specified database name
    • Creates the database with the name given in the DbContext constructor
  • Connection with full connection string
    • The whole connection string can be passed into the DbContext constructor
  • Connection string in app.config/web.config 
    • If the connection string matches name matches the DbContext name, or a string passed to the DbContext constructor, it will be used.  
The technical challenge is to get the connection string from the WPF application where it's entered by the user, to the Web API controller.  The app.config of the compiled WPF shell contains the connection string that will be used by EF.  If this connection is modified, when the application is restarted, EF will use the new connection string as it initializes.

While researching different ways of approaching this on the web, I noticed that several articles referenced the fact that an Entity Framework connection string contained metadata and used the EntityConnectionStringBuilder class. With Code First this is unnecessary.  Also, many examples online use the SqlConnectionStringBuilder to piece together a connection string from several user inputs.  I opted to expose the entire connection as a string. If someone wants to change this they better know what they are doing :)  I do make use of the SqlConnectoinStringBuilder using the ConnectionString property to throw errors if the connection string contains unknown sections etc. This provides a basic level of validation for the connection string.

The user interface is mildly unattractive and simple :)

Here is the code.
If an empty database is created beforehand, the test connection button will provide validation that the connection worked.  If a valid connection string is supplied with a database that does not yet exist, the test connection functionality isn't so useful.  However, EF will in either case create the correct database schema or database and schema upon restarting the application.

This method has a few drawbacks. Every time the application is updated via the ClickOnce installer, the user will have to reset the connection string.  This is because the connection string is an application setting not a user setting.  Another small annoyance is that the application must be restarted for the new connection string to be read and piped over to the OWIN Self Host project. I would love to see a better way of doing this. Suggestions are welcome.

Saturday, January 3, 2015

MVVM Light RelayCommand - Broken & Fixed

If you've done much in the MVVM space, your probably familiar with the MVVM Light Toolkit created by Laurent Bugnion.  I've done a few projects recently using MVVM Light and I noticed that the relay command in WPF was not behaving as it normally did.  It was not magically handling the CanExecuteChanged event to update the status of the RelayCommand.  I decided to take the time to research the problem.  It didn't take long to find the following posted by Laurent on CodePlex for work item 7659

"WPF is the only XAML framework that uses the CommandManager to automagically raise the CanExecuteChanged event on ICommands. I never liked that approach, because of the "magic" part, but this is a "feature" of WPF and of course I have to support it. No question here.

In V5, I moved to portable class library for all the newest versions of the XAML frameworks, including WPF4.5. Unfortunately, there is no CommandManager in PCL, and I have to admit that I didn't realize that at first sight. So of course now the automagical part doesn't work anymore. Again, so sorry about that."

This seems to affect V5 - V5.01, with the fix coming in V5.02. Not long after he posted the fix, which is simply a change in namespace for the RelayCommand when using it with WPF.

"Change the namespace of the RelayCommand class from GalaSoft.MvvmLight.Command to GalaSoft.MvvmLight.CommandWpf."

This does indeed fix the issue :)