How to allow Prism Unity modules to properly Dispose() on Application shutdown

I have a Prism application which uses a Unity DI container to load a bunch of modules which represent various elements of my application.

I recently needed to perform some clean-up in one of my modules when the application exits. Normally this is something I would do with an IDisposable implementation, but in a Prism/Unity setup Dispose never gets hit on the module code.

Here’s how I got around it:

First I created a custom Event to allow me to signal my modules that the container is closing:

public class ApplicationExitEvent : CompositePresentationEvent<string> { }

Then in my bootstrapper I implement IDisposable and fire the event in my Dispose() method:

public void Dispose()
{
  var eventAggregator = Container.Resolve<IEventAggregator>();
  if (eventAggregator != null)
  {
    eventAggregator.GetEvent<ApplicationExitEvent>().Publish("");
  }
}

Then in my module’s Initialize() method I subscribe to this event:

EventAggregator.GetEvent<ApplicationExitEvent>().Subscribe((o) => Dispose(), true);

And put whatever cleanup code I need in my module’s Dispose method. Done!

How to still get Google Apps for free

Ever since google moved their cloud based productivity suite “Google Apps” away from the “we’ll make money from your data” to the “we’ll make money from your money” model they also stopped new sign-ups for their free “Standard Edition” for individuals.

For those late to the party, Google Apps provides most of the standard gmail suite (mail, calendar, contacts, docs (or drive as it’s now called), google+, etc) but for your own domain, with the addition of some user and domain management thrown in. I have been happily using Google Apps for dutton.me.uk and a few of my other domains for years and fortunately this change doesn’t affect existing users.

But there’s still a way to get a Google Apps account, albeit for a single user, through a method they’ve left open for their App Engine developers.

Here’s how: Continue reading

Using data bound properties in the WPF ValidationRule

I recently needed to use to make sure that a number entered into a text box was less than the value of a property on my view model.

Arguably, this sort of business logic might be better off inside my view model; possibly let the property get set regardless, then verify and do something with IDataErrorInfo to notify the GUI if it’s wrong before updating my model data if required. But in this case I am binding straight onto a property which is held inside a class I cannot modify, so I decided to try and use WPF’s built-in binding validation mechanism.

So far so good; off I went deriving from ValidationRule and overriding Validate, but I soon came a cropper trying to access the view model. The problem is that ValidationRule isn’t a DependencyObject so I can’t add a dependency property to bind my view model to, and the specifics of my usage (this TextBox is dynamically generated in a DataGrid in code, but that’s for another blog post), meant that the solution suggested here didn’t help me, the binding fails at the point the TextBox is created so never gets updated when it’s finally set.

So after a bit of a dig about in the MSDN I found that if you set

ValidationStop = ValidationStep.UpdatedValue

on the ValidationRule the value parameter in the Validate method is the BindingExpression itself, from which you can query DataItem to get the binding source object that the expression uses (which in my case is my view model).

Great stuff, but now how do I get my actual value from the BindingExpression? I can’t use SourceValue, or SourceItem, because even though under the debugger they show my value, they are both internal.

So along comes .Net 4.5 to the rescue with a new ResolvedSource property for BindingExpression which will return the binding source object, in this case the TextBox text property which means I can do something like this:

public class NumberIsGreaterThanVmValidationRule : ValidationRule
{
  public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
  {
    var result = new ValidationResult(true, null);

    var vm = ((BindingExpression) value).DataItem as MyViewModel;
    var val = (int)((BindingExpression) value).ResolvedSource;

    if (val.Value < vm.ComparisonValue) result = new ValidationResult(false, "Number is less than allowed value");

    return result;
  }
}

How to fix: “The command you are attempting cannot be completed becuase the file ‘xxx.vdproj’ is under source control and is not checked out” when building solutions containing setup projects in VS2010

Today I revisited some old projects under Visual Studio 2010 to carry out some maintenance. The solution file contains a handful of C# code projects, and two Deployment Projects (vdproj). Every time I tried to build, it would succeed but I would be prompted with this dialog for each Deployment Project.

VS2010 vdproj checked in

Clicking OK or closing the dialog would prompt another to pop-up, at least a dozen or so times before finally finishing the build.

A bit of digging about (some of the links provided in various forums posts have since become broken) and Microsoft released a hot fix back in April 2011 which you can find here. According to one post, the issue is down to a different hashing algorithm employed by Microsoft for generating GUIDs in SP1 of VS2010.

Any deployment projects created before SP1 and checked into source control will then attempt to update the component GUID and popup this error, although I seem to get this on every build if the .vdproj is checked in, regardless of whether VS2010 SP1 has previously updated the file.

Fortunately installing this hot fix makes the problem go away and stops me having to mash my enter key every time I want to build.

Playing with Predicate

I came across a problem during recent round of refactoring. Here’s a contrived simiIar example.

I have an IEnumerable, MyThings contains a property of type Enum called MyThingType. Scattered around my class I found I had quite a bit of duplicated code consisting of a Linq Where statement to filter the IEnumerable based on a specific values of MyThingType and then perform some additional actions on the result.

var filtereredThings = MyThingsList.Where(t => t.MyThingType == ThingType.ThingA);
// other stuff on filteredThings

All good so far, I extracted the common code into a new private method call which returned my result and took the MyThingType as a parameter to filter on, the problem arose when my last Where statement filtered on two MyThingType values.

private IEnumerable FilterAndProcessThingType(IEnumerable data, ThingType filterType)
{
  var filtereredThings = MyThingsList.Where(t => t.MyThingType == filterType);
  // other stuff on filteredThings and return result
}

I changed my method to take a params parameter for the filter so I can pass a variable number of MyThingType in, but how do I change my Linq?

private IEnumerable FilterAndProcessThingType(IEnumerable data, params ThingType[] filterType)
{
  var filtereredThings = MyThingsList.Where(t => t.MyThingType == ???);
  // other stuff on filteredThings and return result
}

This is where Predicate comes in; a Predicate is a function which returns true or false. This means I can dynamically create one to do my MyThingType check and put it in my Where’s Lambda expression.

private IEnumerable FilterAndProcessThingType(IEnumerable data, params ThingType[] typeFilter)
{
  var thingTypeMatcher = new Predicate<tuple<thingtype, thingtype[]="">>(t =>
  {
    var thingType = t.Item1;
    var thingTypeArray = t.Item2;
    return thingTypeArray.Aggregate(false,(current, type) => current | thingType == type);
  });
  var filtereredThings = MyThingsList.Where(t => thingTypeMatcher(new Tuple<thingtype, thingtype[]="">(t.MyThingType, typeFilter));
  // other stuff on filteredThings and return result
}

And that’s it, now I can pass a variable number of types to match into my common code.

How to fix: “The Windows Phone Emulator wasn’t able to create the virtual machine: Generic failure” under VMWare Fusion 4.1.4

I use an iMac at home, so any Windows development is done in a Windows 8 virtual machine running under VMWare Fusion 4.1.4.

I ran into a problem this evening when playing around with some Windows Phone 8 development and thought I’d share the solution. It turns out the default Fusion configuration doesn’t support the hardware assisted visualization (Hyper-V) that the Windows Phone SDK Phone Simulator uses.

Not to worry, just do the following (works for me under 4.1.4). Continue reading