Monday, 23 July 2012

Build process for MTS

I've now come back to this project after finishing off another for the time being.  My first job was to do some improvements to the infrastructure.

The first improvement was to migrate to NuGet packages and a package restore workflow as opposed to a commit packages to version control workflow.  Here's an article that describes how this can be done:

http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages/

I could then write a batch file to restore references and rebuild the application without having the overhead of all the binaries under source control.  Very neat.

I've also now upgraded to EntityFramework 4.3.1 and am now using migrations instead of the old teardown and re-create database model.

Here's some useful links regarding EF 4.3. and migrations:
http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-automatic-migrations-walkthrough.aspx
http://blogs.msdn.com/b/adonet/archive/2012/02/09/ef-4-3-code-based-migrations-walkthrough.aspx
http://blogs.msdn.com/b/adonet/archive/2012/01/12/ef-4-3-configuration-file-settings.aspx
http://www.ladislavmrnka.com/2012/03/ef-4-3-migrations-and-existing-database/

I'm now ready to extend the build process to running unit tests and building an installer for the application.  Ideally, I want to be able to install remotely.  This is something new that I'll need to look into.

Friday, 25 May 2012

Multiline editing

I wanted to allow the user to enter an address as a multi-line field rather than a group of single line edit boxes.  In winforms, you can set the multiline property to true, but in WPF, you need to set 3 properties as described in this article;

http://adnan8t2p.blogspot.co.uk/2009/03/wpf-multiline-textbox.html


Friday, 18 May 2012

LINQ to dictionary

In the latest story, I wanted to list received manuscripts in deadline ascending order so that the user could prioritise their work.  As the deadline field is part of the job entity, it wasn't as simple as just fetching a list of manuscripts.  In needed the LINQ to return a dictionary of manuscript and deadline key pairs. Here is an article that I found that shows how this can be done:

http://stackoverflow.com/questions/245168/linq-to-sql-todictionary


Thursday, 10 May 2012

Styles, Data Triggers and State Machines

Highlighting ListView Items

I've not needed to post on here for a while as I've been busy building out Oxyrhynchus.  Today I added a feature to display jobs that had been invoiced for, but were unpaid.,  The requirement was to have unpaid jobs that were 30 days past the invoice raised date to be highlighted.  I found a good article explaining how to use style resources and data triggers to achieve this on the view:

http://www.codeproject.com/Articles/18585/Highlighting-Items-in-a-WPF-ListView


Replacing status enums with State Pattern

While fixing a small problem with the quick action button logic I became aware that my manuscript workflow logic had become distributed between three classes -  the EntityBase class contained some default logic and the Manuscript and ManuscriptService classes also contained the received to returned state transitional logic.  Although this is manageable now, it could quickly turn into a 'code smell' that would require refactoring.  Typically, this would be addressed by refactoring to the State pattern and have state-based behaviour encapsulated.  I've done some reading around this:

http://stackoverflow.com/questions/7217125/how-to-map-abstract-class-using-entity-code-first-and-state-pattern
http://stackoverflow.com/questions/10011859/state-pattern-and-domain-driven-design

Saturday, 5 May 2012

Separation of concerns

Spent most of the day building out functionality by adding the ability to mark a manuscript found, from the smart search results list.

I don't want the smart search to know anything about individual domain entities such as jobs and manuscripts.  I want the view-model to work with the abstract EntityBase.  I used the EventAggregator to publish actions that the relevant modules could subscribe to.

Thursday, 3 May 2012

Data Templates for Hetrogeneous Collections

Today, I added manuscripts to the smart search module.  This meant that my search results needed to display a representation of both contact and manuscript data in the results list.  One simple way to achieve this would be to implement a common interface that a single data template would present.  However, I wanted the flexibility of different representations for the differing data types.  The solution to this is to use the DataType property on DataTemplate to create an implicit data template.  This had the effect of applying the template to all instances of that type.

See DataType property section in this article:
http://msdn.microsoft.com/en-us/library/ms742521.aspx


Tuesday, 1 May 2012

Prism Event Aggregator

Before I start on the manuscript workflow stories, I wanted to split out the manuscript entry view from the job module into it's own module.  I then wanted the job module to fire an event when it opened the job details view, so that the new manuscript module knew when to open and embed the manuscript entry view.

The event aggregator mechanism provided by the prism library is quite straightforward.  However I did run into a problem that when I published an event, the subscriber didn't pick it up.  The issue was down to weak references and the fact that the module instance is garbage collected almost straight after initialisation.

Here's an article that explains the situation:

http://neverindoubtnet.blogspot.co.uk/2009/05/prism-event-aggregator-subscription.html

Wednesday, 18 April 2012

Scoped Region Managers

I wanted to compose my manuscripts entry view within the job details view to give it some context. So, I added a region to my job details view and refactored my OpenView call so that it took a region name. This worked fine for the the first job, but broke the second time because the second job details view instance tried to register the same region name with the global region manager as the first one.

The solution to this is to use scoped region managers. When adding a view to a region using injected (rather than discovered) views, you can request that it creates a new RegionManager that you can pass to the ViewModel to use when creating the nested view. Here are some articles about this approach:

http://msdn.microsoft.com/en-us/library/ff921098%28v=pandp.40%29.aspx

http://stackoverflow.com/questions/6582612/prism-4-locally-scoped-regionmanager

Tuesday, 17 April 2012

ViewModel level acceptance testing

In the past, when writing acceptance tests for a project, I've usually used a GUI automation tool such as White (for desktop) or Selenium RC (for web apps). For this project I wanted to try something a bit different. I wanted take full advantage of the fact that I'm using the M-V-VM pattern and start acceptance test cases from the ViewModel rather than the View.

So instead of the tests firing up an instance of the compiled app, I've created an acceptance test bootstrapper that creates all the unity mappings that the application bootstrapper does, but replacing the mappings for UI related resources with RhinoMocks mock objects. This bootstrapper is called by the SpecFlow test framework before the tests start. This means that I can run virtually end-to-end tests on the application without any screen/keyboard/mouse interaction. This sort of test suite is ideally suited to being run on a build machine.

Another difference to the automation approach was that I change the way the database was initialised when the tests start. Usually the database will be dropped and rebuilt each time the model changes. For the acceptance testing, the database is re-created on each run. This provides a consistent data environment for the test to run in. To get this to work, I needed to set up a separate NUnit project that reloaded the test assembly for each run. This ensured that the Unity container would be re-created and the DBContext object singleton would initialise the database.

Monday, 16 April 2012

Testing the ViewOpener

I've added a new class and interface to the shell to allow modules to create views that cannot be reached from the menu. An example of this is the job details view which will be opened after adding a job and later on, from one of the job search screens.

I was running into a problem when testing this class that the tests needed to be run in an STA thread (Single Thread Apartment) as opposed to a MTA (Multi Threaded Apartment). This was because I needed to mock the views down to FrameworkElement level so I could access the DataContext property. As FrameworkElement requires to run in STA, I had to ensure that my tests run in STA. Here's an article I found on how this is down using NUnit 2.5 or higher.

http://madcoderspeak.blogspot.co.uk/2008/12/getting-nunit-to-go-all-sta.html

Friday, 13 April 2012

MVVM Validation

OK, I think I've finally broken the back of implementing the validation for the new job entry view. The first problem was that there was 2 types of validation going on. Firstly, there was binding error validation (for example, when I was binding from a text box to the budget (double) model property and I typed in some characters). The second type was the validation rules that I had added to my model through the IDataErrorInfo interface. I needed a way for my CanExecute evaluation method to pick up both types of validation.

I found a very useful article that did just this. I needed to introduce some base class logic for my View and ModelView:

http://karlshifflett.wordpress.com/mvvm/input-validation-ui-exceptions-model-validation-errors/

This solution had the added benefit that it made the binding exception errors more readable to the user when viewing them through the tool tip.

To get the validation solution to work, I needed to do several things:
  1. Make all my bindings TwoWay rather than OneWayToSource.
  2. Make all of my ModelView properties call NotifyPropertyChange, when set.
  3. Turn NotifyOnValidationError, ValidatesOnDataError and ValidatesOnException on on all my bindings.
  4. Use a RelayCommand instead of a DelegateCommand.
  5. I needed to change the type of the view from UserControl to BaseView.
This last change meant that I needed to be able to specify the generic type in XAML as well as the partial class. I found and article that explained how to do this:

http://www.codeproject.com/Articles/37317/Generic-Support-In-XAML

Next up is to start working on adding manuscripts to a job. Firstly I want the new job screen to close on successful save and a new screen open that shows the job title, number, contact name and process icons and provide a way to add the new manuscripts.

Thursday, 12 April 2012

Binding radio buttons to Enums

Found a good article that had the solution to binding radio buttons to Enums and not breaking the validation:

http://stackoverflow.com/questions/397556/how-to-bind-radiobuttons-to-an-enum

Also found another article about Enum Bit Flags which I might use to refactor the process flags on the new job screen.

http://msdn.microsoft.com/en-us/library/cc138362.aspx

I need to do some further reading to work out how to integrate the IDataErrorInfo calls with the CanExecute delegate. My initial investigations came up fruitless.

Wednesday, 11 April 2012

EF 4.1 doesn't support emums!

Whist building out the application with the job status and budget type found out that EF 4.1 doesn't support enum property mapping to database field. The properties just get ignored. To get around this, I had to add integer properties and wrap these in my enum properties.

Started having a look at the validation for the new job entry. I've been using IDataErrorInfo on the ViewModel to validate and report errors. This shows up on the screen as a red border around the control. I still need to find out how the mouse-over hint shows the error text. I also need to find out how I can integrate validation with the drag and drop functions. Because the user isn't entering data directly into the control, the same binding technique cannot be used.

Monday, 9 April 2012

Smart Search & Drag and Drop

Smart Search

One of the requirements is to be able to find existing contacts in the system and add them to a new job. I created a smart search where I could type a few characters of a name and it would list matches. I could then drag a matching contact over to the new job and insert it into the contact placeholder. This was simple enough, but I did run into a problem where the entity framework was creating new contact records rather than linking to the existing ones. This was because I was using separate EF context objects for the contacts and the jobs. So, when I save the new job, the context object had not recognised the contact as one that was already in the system. I fixed this by creating a factory method that returned a singleton instance of the EF context that both the contact and job data access classes could use.

Drag and Drop

To perform the drag and drop from the smart search to the new job view, I used some drag and drop code that I had used in the Prediction League application. I realised that if I was to use drag and drop extensively, I'd be copy and pasting this code into multiple views. What I really needed was to extract and generalise the code so that I could plug the drag and drop strategies in where needed. I managed to do this and learned a bit about using generics at the same time.

I'm going to look into a WPF drag/drop library on Google Code that uses attached properties to that the drag drop code can be written in the ViewModel rather than the view code behind.

http://code.google.com/p/gong-wpf-dragdrop/

Saturday, 7 April 2012

Oyrhynchus

Manuscript Tracking System is a rather uninspiring name for an application so I came up with Oxyrhynchus. Oxyrhynchus is a city in Egypt where they found a shed-load of ancient manuscripts. It sounds sort of weird as well, so I've borrowed it.

Technologies:

I'm using Prism 4.1 and the built in unity bootstrapper along with WPF 4. I'm intending to use SpecFlow for BDD and NUnit and RhinoMocks for the TTD. I'll be using Entity Framework Code First for the database layer.

UI Design:

I've designed a shell layout that has a menu on the left hand side, a main work area in the middle that is contained in a tab control. On the right side, I will have a smart search facility which will feature drag and drop of found items into the main area. The modules will register menu items with the shell, and the shell will manage the opening and closing of these views.

Thursday, 22 March 2012

Tracking Manuscripts

I'm a big believer in learning new skills by doing for real. So, when I asked my family members if they could think of a software application that they would use on a regular basis, it was my intention to develop these applications and see them go live.

One of these ideas came from my proofreading and copy editing mother. She wanted a new manuscript tracking system. Her old system was no longer supported by the vendor, so when she upgraded to Windows 7, she found that the software no longer worked. Since then, she has been using an MS Works database to track manuscripts. This does the job, but doesn't have the nice features that she was used to.

This project will involve a couple of firsts for me:

Firstly, I will be writing the application using C# and Windows Presentation Framework. Previously, all my desktop development work had been using Winforms and before then Delphi. So I'm expecting quite a learning curve involving the WPF platform, MVVM and possibly PRISM. I'm also going to be using the Entity Framework in code first mode.

Secondly, it will be the first time I have developed a real-life application from ground up using Behaviour-Driven-Development and Test-Driven-Development approaches from the very beginning. I've used these approaches before on smaller sub systems, so it will be interesting to develop a full code-base using these methods.

So here, I will try to document the journey from idea conception to going live and beyond.