MVVM model letting the user select a directory in a testable manner My application needs to let the user select a folder from somewhere on their local machine. Below are the interface and model pair that I have written to let the user do so.

public interface IFolderPicker
{
    //  Methods
    //  =======

    string Show();
}


using Microsoft.WindowsAPICodePack.Dialogs;
using WinForms = System.Windows.Forms;

public class FolderPicker : IFolderPicker
{
    //  Constants
    //  =========

    private const string SelectATargetFolder = "Select a target folder";
    private const string CDrive = @"C:\";

    //  Variables
    //  =========

    private readonly bool isPlatformSupported;
    private readonly WinForms.FolderBrowserDialog xpFolderBrowserDialog;
    private readonly CommonOpenFileDialog vistaFolderBrowserDialog;

    //  Constructor
    //  ===========

    public FolderPicker()
    {
        isPlatformSupported = CommonFileDialog.IsPlatformSupported;

        xpFolderBrowserDialog = new WinForms.FolderBrowserDialog
        {
            Description = SelectATargetFolder
        };

        vistaFolderBrowserDialog = new CommonOpenFileDialog
        {
            Title = SelectATargetFolder,
            IsFolderPicker = true,
            DefaultDirectory = CDrive,
            AllowNonFileSystemItems = false,
            EnsurePathExists = true,
            Multiselect = false,
            NavigateToShortcut = true
        };
    }

    //  Deconstructor
    //  =============

    ~FolderPicker()
    {
        xpFolderBrowserDialog.Dispose();
        vistaFolderBrowserDialog.Dispose();
    }

    //  Methods
    //  =======

    public string Show()
    {
        if (isPlatformSupported)
        {
            return SelectWinVistaOrLaterFolder();
        }
        else
        {
            return SelectWinXPFolder();
        }
    }

    private string SelectWinXPFolder()
    {
        WinForms.DialogResult result = xpFolderBrowserDialog.ShowDialog();

        switch (result)
        {
            case WinForms.DialogResult.OK:
            case WinForms.DialogResult.Yes:
                return xpFolderBrowserDialog.SelectedPath;

            default:
                return null;
        }
    }

    private string SelectWinVistaOrLaterFolder()
    {
        CommonFileDialogResult result = vistaFolderBrowserDialog.ShowDialog();

        switch (result)
        {
            case CommonFileDialogResult.Ok:
                return vistaFolderBrowserDialog.FileName;

            default:
                return null;
        }
    }
}



My reasoning for this design is that now the 3 readonly variables can be mocked in unit tests via reflection, while this isn't an ideal way of doing it, it's better than nothing.

While I am looking for all feedback, my focus here is on the WinForms.FolderBrowserDialog and the CommonOpenFileDialog. They both implement the IDisposable interface and my concern is that I might not be implementing that properly?
I believe that I could make the IFolderPicker interface extend the IDisposable interface and then call the two .Dispose() methods from within the inherited Dispose method but I was hoping I could insulate the rest of my program from these two classes as much as possible - is disposing of them in the deconstructor like this also valid?

Originally I had both these classed being instantiated in their respective Select...() methods in a using block. But while also not being mock-able, it meant they were being newed up each time the method was called - is this current implementation better than that?
Review


You always instantiate inner dialogs for both platforms, even though one will never be called. Your platform will not change at runtime. Use the Lazy pattern to only instantiate the required dialog at first access.
Rather than returning the magic path null, I would opt to use a TryShow method returning a boolean whether a path got selected an an out parameter for the path.




Object Destruction

From Programming Guide: Destructors:


  The programmer has no control over when the finalizer is called
  because this is determined by the garbage collector. The garbage
  collector checks for objects that are no longer being used by the
  application. If it considers an object eligible for finalization, it
  calls the finalizer (if any) and reclaims the memory used to store the
  object.


Since your class is not sealed, derived classes can be made. These classes will not be able to control the order of finalisation code. The order of destructors is fixed as this snipped from the link shows:


protected override void Finalize()  
{  
    try  
    {  
        // Cleanup statements...  
    }  
    finally  
    {  
        base.Finalize();  
    }  
}



That's why you should implement the dispose pattern instead. It allows for more flexibility in flow and distinguishes between disposing managed vs unmanaged code. 



Unit Tests


  My reasoning for this design is that now the 3 readonly variables can be mocked in unit tests via reflection, while this isn't an ideal way
  of doing it, it's better than nothing.


When writing code with testability in mind, you don't want to resort to reflection to mock private state of your classes. There are a couple of options available:


Make the private methods protected virtual. Mocking frameworks and derived classes are able to override the methods. Partial mocks could be used in this case.
Wrap both internal dialogs behind a custom interface, injected into the outer class. The class no longer has dependencies on native win and vista components and interfaces are easy to mock.