Simplified MEF Export Provider using MEF Property Exports

674ladderAll of my projects recently use MEF to handle all dependency injection in both the service layer and in the view models (PRISM).  I recently needed to be able to inject a different implementation of a particular interface to all of the imports that called for that interface.  All based on a setting or a flag. 

The Problem…

Our current project communicates with a pump module that is the main hardware unit for the application, and that uses a serial port to connect with the pc and our software. I have already written a system layer service library for talking to the pump. The main application also has a pump service that is in the application layer and that is the communication point for the system service. All of the services have an interface defined in Core.Interfaces and this is where the user interface modules can reference the application services, such as in the view models. The interfaces are implemented by classes in the Application Services library including the Pump Service interface, aptly named IPumpService.

Some Context:
Here are some links for technologies used in the project that you can use for references for this article.

As the project has proceeded there are many services that use the pump service to talk to the pump module and all of these services import the IPumpService interface into their constructors using the ImportingConstructor attribute from MEF. This makes it easy for any service that needs the pump to access it, but that also means there are many instances of the class that implements the IPumpService interface in existence and being used. Which in turn means that if I wanted to replace the current implementation of IPumpService with an alternative, let us say a pump simulation class, I have a lot of places that would need to be altered.

So that is the goal…

Find a way to quickly (no budget for a simulator so all simulator work must not eat into project time) implement a substitution class for the existing IPumpService that will allow all MEF Imports to get the PumpSimulator implementation instead of the real one, if a config setting is true.  I have all of these services that import IPumpService into their constructor. Each of these services depends upon the pump service for various boolean flags and other commands. The PumpService class implements IPumpService and is therefore instantiated by MEF and imported into the constructors of the dependent classes. I want to be able to run the application without the physical hardware and thereby speed up development and testing (we only have one prototype of the pump instrument). The simulator also implements IPumpService but is called PumpSimulator.

Some Options:

So how do I use MEF to replace all of the currently imported instance of IPumpService which is PumpService, with an alternative implementation of IPumpService, my PumpSimulator class?

Most of our MEF exports are implementations of the various service interfaces. Lets look at some code, for one of the services that we mentioned are the consumers of the IPumpService export.  The ManifoldService manages the pump manifold and must talk to the pump to perform installation and removal workflows for the manifold parts.  Here is declaration of the service and its constructor (with importing attribute in place):

   1: [Export(typeof(IManifoldService))]

   2:     public class ManifoldService : IManifoldService

   3:     {

   4:         private readonly IAlertService _alertService;

   5:  

   6:         private readonly IAuditService _auditService;

   7:  

   8:         private readonly IConsumablesService _consumablesService;

   9:  

  10:         private readonly IDataService _dataService;

  11:  

  12:         private readonly IEventAggregator _ea;

  13:  

  14:         private readonly CancellationTokenSource _lifetimeTasksCanceller = new CancellationTokenSource();

  15:  

  16:         private readonly ILogger _logger = LoggerFactory.GetLogger(LogCategory.ExecutionFlow, typeof(IManifoldService));

  17:  

  18:         private readonly IPumpService _pumpService;

  19:  

  20:         private readonly ITaskFactory _taskFactory;

  21:  

  22:         protected Task _expiredTask;

  23:  

  24:         private bool _isInstallationComplete;

  25:  

  26:         private bool _isManifoldFlushRequired;

  27:  

  28:         private Manifold _manifold;

  29:  

  30:         private ISolution _universalIngredient;

  31:  

  32:         protected Task _warningTask;

  33:  

  34:         /// <summary>

  35:         /// Initializes a new instance of the <see cref="ManifoldService" /> class.

  36:         /// </summary>

  37:         /// <param name="ea">The event aggregator instance.</param>

  38:         /// <param name="pumpService">The pump service.</param>

  39:         /// <param name="auditService">The audit service.</param>

  40:         /// <param name="alertService">The alert service.</param>

  41:         /// <param name="consumablesService">The consumables service.</param>

  42:         /// <param name="dataService">The data service.</param>

  43:         /// <param name="tasks">The tasks.</param>

  44:         [ImportingConstructor]

  45:         public ManifoldService(

  46:             IEventAggregator ea,

  47:             IPumpService pumpService,

  48:             IAuditService auditService,

  49:             IAlertService alertService,

  50:             IConsumablesService consumablesService,

  51:             IDataService dataService,

  52:             ITaskFactory tasks)

  53:         {

  54:             _auditService = auditService;

  55:             _alertService = alertService;

  56:             _pumpService = pumpService;

  57:             _consumablesService = consumablesService;

  58:             _dataService = dataService;

  59:             _taskFactory = tasks;

  60:  

  61:             _ea = ea;

  62:             _ea.GetEvent<ApplicationStartedEvent>().Subscribe(OnApplicationStarted);

  63:             _ea.GetEvent<ApplicationShuttingDownEvent>().Subscribe(OnApplicationShutdown);

  64:             _ea.GetEvent<PrimeCompletedEvent>().Subscribe(SetManifoldFlushRequired);

  65:             _ea.GetEvent<DispenseStoppedEvent>().Subscribe(OnDispenseStopped);

  66:             _ea.GetEvent<UniversalIngredientChangedEvent>().Subscribe(CheckForUIChange);

  67:             _ea.GetEvent<TransferSetChangedEvent>().Subscribe(ts => CheckForUIChange(ts.UiStationNumber));

  68:         }

  69:  

  70:         // ...

  71: }

As you can see all of the dependencies, including our IPumpService are imported using MEF’s ImportingConstructor and this technique is used throughout the project.  The constructor simply assigns local private holders for the services and wires up some aggregated events.  The key point here is the import of the IPumpService as a ctor parameter, and how I can replace it with an alternate implementation of IPumpService (my PumpSimulator class) without putting code in production that is like my first solution below.

My first solution…

Was not elegant and certainly not ideal.  It was originally just temporary fix I used to be able to run the manifold service workflows without being connected to the pump.  The real IPumpService implementation requires a connection to the hardware to function, and I did not want to alter that.  So I simply added code to the Manifold Service constructor to hijack the local private holder for IPumpService.  Like this:

   1: [ImportingConstructor]

   2: public ManifoldService(

   3:     IEventAggregator ea,

   4:     IPumpService pumpService,

   5:     IAuditService auditService,

   6:     IAlertService alertService,

   7:     IConsumablesService consumablesService,

   8:     IDataService dataService,

   9:     ITaskFactory tasks)

  10: {

  11:     _auditService = auditService;

  12:     _alertService = alertService;

  13:     _pumpService = pumpService;

  14:     _consumablesService = consumablesService;

  15:     _dataService = dataService;

  16:     _taskFactory = tasks;

  17:  

  18:     _ea = ea;

  19:     _ea.GetEvent<ApplicationStartedEvent>().Subscribe(OnApplicationStarted);

  20:     _ea.GetEvent<ApplicationShuttingDownEvent>().Subscribe(OnApplicationShutdown);

  21:     _ea.GetEvent<PrimeCompletedEvent>().Subscribe(SetManifoldFlushRequired);

  22:     _ea.GetEvent<DispenseStoppedEvent>().Subscribe(OnDispenseStopped);

  23:     _ea.GetEvent<UniversalIngredientChangedEvent>().Subscribe(CheckForUIChange);

  24:     _ea.GetEvent<TransferSetChangedEvent>().Subscribe(ts => CheckForUIChange(ts.UiStationNumber));

  25:  

  26: #if DEBUG

  27:             if (Constants.UsePumpSimulator)

  28:             {

  29:                 _pumpService = ServiceLocator.Current.GetInstance<IPumpService>(Constants.Simulator);

  30:             }

  31: #endif

  32:  

  33: }

In lines 26 –31 I have simply added some code to reassign the _pumpService private variable to hold an instance of the PumpSimulator.  Again, both the PumpService and the PumpSimulator classes implement IPumpService so this was not a problem to make the assignment, ugly as it may be.  And it worked, temporarily.

The issue quickly arose again however when I needed another service to use the simulator also.  I was faced with the choice of continuing to alter the constructors, knowing I would have to remove this code before the next release, or come up with something better.  To Google!

Some quick Google research led me to MEF Export Providers, however I had very little time to solve this problem, less that it would have taken for me to implement a custom Export Provider.  I would like to stress that my eventual solution may not be “best practice”, it is however simple and it works and violates no major points that I am aware of.  But, that said, I would also like to emphasize that an ideal solution, given the time and budget to implement it, would be a custom export provider that could use whatever conditions I would like to load the correct IPumpService implementation when asked for it by the catalog. 

One other reason why I did not want to use a custom export provider at this point was the fact that you have to pass the custom provider implementation to the catalog which in my case, using Prism, is in another project in the Bootstrapper.cs file.  I wanted to only make a simple alteration with as small a footprint as possible to the Application Services layer which is its own class library.  I did not particularly want to alter the main executable which is where Bootstrapper.cs lives and is where the MEF catalog is constructed.  Our current architecture requires no references to the application services library by project upstream, such as the main executable or the UI modules.  These projects all reference Core and Core.Interfaces which is where all of the service interfaces (IPumpService) live.  Using a custom provider at the level of the bootstrapper may have resulted in me having to reference the implementations of IPumpService directly (to construct them for export) and I did not want to do that.

Simplified Custom MEF Export Provider

That is when I found this information (https://mef.codeplex.com/wikipage?title=Declaring%20Exports)  about using properties to export.  This lead me to figure out a simple way of alternating my IPumpService export between the two implementations. Using a property export meant I now had a way to get both of my implementations together into a class and then choose the exported instance based on a config setting.

I had used property imports before, usually to load service lazily in order to avoid cyclic dependency problems, but I was not aware you could use a property to export  and thereby satisfy other imports.  Basically, you can use the Export attribute on a property of the type you need to use to satisfy an import elsewhere, such as the importing constructor of my pump dependent services, such as Manifold service we have already seen.

First I got rid of my pump simulator related constants and created a new setting in the application’s app.config file (I used the main exe config file, but in retrospect I could have used an app.config added to the Application Services project to further tighten the encapsulation at the service layer), called “UseSimulator” with a value of “true”. 

I then created a small class called PumpServiceProvider that used the importing constructor attribute to import both PumpService and PumpSimulator. I changed both of their class declarations to use a plain Export attribute instead of exporting typeof(IPumpService). So now I had no IPumpService export but I did have exports for PumpService and PumpSimulator, both of which I imported into my new provider class.

PumpServiceProvider Class:

   1: [Export]

   2: public class PumpServiceProvider

   3: {

   4:     private readonly ILogger Logger = LoggerFactory.GetLogger(LogCategory.ExecutionFlow);

   5:  

   6:     private readonly bool _useSimulator;

   7:  

   8:     public PumpServiceFactory()

   9:     {

  10:         if (!bool.TryParse(ConfigurationManager.AppSettings["UseSimulator"], out _useSimulator))

  11:         {

  12:             Logger.Log(LogLevel.Error, "Failed to parse config setting for UseSimulator.");

  13:             _useSimulator = false;

  14:         }    

  15:     }

  16: }

The constructor simply loads the app configuration setting used to determine whether to use the simulator implementation of IPumpService or the real implementation. 

I then added a single property to my PumpServiceProvider class called ActivePumpService that was of type IPumpService and had an export tag like this:

   1: [Export(typeof(IPumpService))]

   2: public IPumpService ActivePumpService

   3: {

   4:     get

   5:     {

   6:         return _useSimulator ? PumpSimulator as IPumpService : PumpService;

   7:     }

   8: }

This property satisfies all Imports of IPumpService throughout the application, because I removed the Export attribute from the two implementations of IPumpService and only have this sole Export of type IPumpService.  I then added two more properties to the class, one for each of the types of pump service implementation.  As such:

   1:  

   2: [Import]

   3: private PumpService PumpService { get; set; }

   4:  

   5: [Import]

   6: private PumpServiceSimulator PumpSimulator { get; set; }

   7:  

These are used in the Get statement of the ActivePumpService property above, based on whether or not the useSimulator flag is true.  And that did it.  It actually worked the first time I tried it, which is always really cool.  I had a very low impact, small footprint solution to my simulator injection problem. 

Conclusion

The most important advantage of this solution in the end, was the fact that it involved no alterations to the dozen or so classes that are consumers of the IPumpService interface.  I was able to accomplish my goal as stated at the beginning of the post, and provide an alternate simulator implementation for my pump service with only minimal additions in the form of my PumpServiceProvider class.

Here is the complete version of the provider class:

   1: [Export]

   2: public class PumpServiceProvider

   3: {

   4:     private readonly ILogger Logger = LoggerFactory.GetLogger(LogCategory.ExecutionFlow);

   5:  

   6:     private readonly bool _useSimulator;

   7:  

   8:     public PumpServiceFactory()

   9:     {

  10:         if (!bool.TryParse(ConfigurationManager.AppSettings["UseSimulator"], out _useSimulator))

  11:         {

  12:             Logger.Log(LogLevel.Error, "Failed to parse config setting for UseSimulator.");

  13:             _useSimulator = false;

  14:         }    

  15:     }

  16:  

  17:     [Import]

  18:     private PumpService PumpService { get; set; }

  19:  

  20:     [Import]

  21:     private PumpServiceSimulator PumpSimulator { get; set; }

  22:  

  23:     [Export(typeof(IPumpService))]

  24:     public IPumpService ActivePumpService

  25:     {

  26:         get

  27:         {

  28:             return _useSimulator ? PumpSimulator as IPumpService : PumpService;

  29:         }

  30:     }

  31: }

 
and only 30 lines to provide all of my IPumpService consumers with a simulator!  MEF saves the day.

Unit Testing ViewModels In Prism Modules

PRISM + WPF = MVVM

All of my recent projects at work have been WPF  applications designed using the Microsoft PRISM framework for composite/modular applications.  PRISM provides the ability to modularize our applications into separate UI modules that are decoupled from the main application and they are developed in a separate project and compiled into their own dll.  The UI module project has a bootstrapper class (of sorts) that implements the IModule interface, and in doing so, registers its views with a region in the main window.  So basically, if the dll is there then the content will show up in the main UI and if it is not, it won’t.  This is an over simplification but I am just trying to provide some context for the main issue that I want to post about.  Let us look at a simple example, a configuration/settings module.  We would have a main region (see the web for more information on Prism Regions) that is likely a tab control with a tab for each major piece of the user interface, i.e. a Reports tab, a Help tab, etc.  The settings module would be a separate project and show up in the main window as its own tab.  PRISM will only show the settings module/tab if its dll is found in the bin of the application.  The settings bootstrapping class tells PRISM that it has views and which region within the main window’s layout to which the view should be linked.  Here is some code:

[code language=”csharp”]

[Module(ModuleName = "SettingsModule")]
[ModuleExport(typeof(SettingsModule), InitializationMode = InitializationMode.WhenAvailable)]
public class SettingsModule : IModule
{
private readonly IRegionViewRegistry _regionViewRegistry;

[ImportingConstructor]
public SettingsModule(IRegionViewRegistry registry)
{
_regionViewRegistry = registry;
}

public void Initialize()
{
_regionViewRegistry.RegisterViewWithRegion(RegionNames.NavigationRegion, typeof(SettingsViewItemControl));
_regionViewRegistry.RegisterViewWithRegion(RegionNames.MainRegion, typeof(SettingsView));
}
}

[/code]

This is a simple implementation of the Microsoft.Practices.Prism.Modularity.IModule interface within PRISM framework.  This interface tells PRISM that this is a UI module and should be made available.  Note now the SettingsView is registered with the Main Region, which in our MainWindow xaml is a tab control marked as a PRISM region using a special attribute.

Okay, enough background.  I think it is safe to assume some familiarity with these topics or else you would not be reading this type of post.  I want to just share some experiences I had recently while writing unit tests for my “Settings Module” (the names and code types have been changed to protect the innocent).  It has never come easy, thought-process-wise, when I went to write some unit tests for my user interface classes.  So, I am posting about that thought process and sharing the resulting unit tests.  I realize that I have virtually zero audience for my blog, but on the off chance that some other developers do read this, I would sincerely benefit from any constructive feedback on my process and my unit tests.  Unit testing is a big part of my work (as it should be for all developers, right?) and I have been focusing my studies (recently, The Art of Unit Testing 2nd Ed., Roy Osherove) on this area and on the improvement of my unit tests, both in best practices and in code coverage.  So…

Solution Structure

My latest feature/task at work was a configuration module (and the service that supports it) for another WPF, touch-first, application, using all of the latest goodies (Entity Framework, MEF, PRISM, .NET 4.5).  The requirements indicated that I would have a tabbed user interface with about a half-dozen different tabs, each containing a logical group of application settings that the user should be able to edit.  I set up a main settings view that held a tab control and defined a local region so that I could separate each settings tab into its own view/view model pair.  This allowed me to maintain consistency with the design of the other UI modules and with our normal best MVVM practices.  Each settings tab had a view which contains the xaml for the ui and a view model class that defines the interaction logic for the view.  So, for example, the first settings tab would consist of UserManagementSettingsView.xaml and UserManagementSettingsViewModel.cs.  Just for some further context the solution/project structure might look like this:

SolutionExplorerScreenShot

This, of course, is just a sample structure that I just created in an empty/new solution so that I could grab a screen shot of it for this article.  I do not want to use actual code/solution from my work as it is all protected by confidentiality and it is all considered a work product that is owned by our clients, not by myself.  Don’t want to get myself into any trouble.  But, that said, I think that you can get the idea form this sample structure.  The Modules.Settings project is laid out like all of the other ui modules that I might make for an application.  There are directories for views, view models and controls, with the SettingsModule.cs class in the root of the project.  This is the bootstrapper for the module and where the above shown code might live, implementing the IModule interface and tying the various views in the ui module to their respective regions in the layout.  In the case of our example “Settings” module I would make a containing view for the modules content that is a tab control and would define a local PRISM region called Settings region.  Each of the individual settings views, i.e. ReportSettingsView would then be registered with the SettingsRegion and would consequently show up in the tab control that is defined in SettingsView.xaml.  So I would end up with a Settings view that was filled with various settings tabs.  All nice and structured.

You might also note there is a ViewModels directory within the module project where all of the ViewModel classes live.  Each view has a corresponding view model class, named accordingly.  This is typical of the MVVM design pattern that PRISM employs.  Each view’s view model contains properties that define any values and/or commands that are used to create the view.  So, for instance, in a ReportSettingsView I might want to display settings for Default Printer, Default Paper Size, and other reports related settings.  Consequently the ReportSettingsViewModel class would have properties for these values that bind to the xaml in the view and that is how data is displayed.  This binding and population of values in the view is fundamental to the MVVM pattern.  There is nothing in the view’s code-behind except coded to tie the view model in and a call to InitalizeComponents which creates the views content.

The unit tests that are needed for this type of UI module class library center around the view model classes, not the views.  The views themselves have very little code, as I mentioned, only what is needed to set the view model to the right type and to initialize the xaml.  All of the unit test fixtures will be matched to view model types, not to the view types.  Therefore I will have a unit test project called WpfApplication1.Modules.Settings.Tests that corresponds to this class library and that will contain all of the test fixtures.  Here is another shot of the structure for the unit test project for this ui module.

SolutionExplorerScreenShot2

Notice that the structure of the test project matches that of the module’s class library project shown in the previous screenshot.  Any test fixture class is located in the same place within that structure, so all of the view model fixtures are in the ViewModels directory the same as the view model classes themselves are.  This is a habit I have always had, not sure where I picked it up, that makes it easy to match a test fixture to a class.  The employed naming conventions also go to that end, the word Test or Tests is added to the tested unit’s name so that matching tests to units is that much easier.

Notice also, that there are no test fixture classes for the views, and no Views directory within the Test project’s structure.  Again, the views are not unit tested.  There isn’t really anything to test in them.  Just to prove that point, for anyone that may doubt that, here is the code behind for one of our example views:

[code language=”csharp”]

namespace WpfApplication1.Modules.Settings.Views
{
/// <summary>
/// Interaction logic for SettingsView.xaml
/// </summary>
public partial class SettingsView
{
/// <summary>
/// Initializes a new instance of the <see cref="SettingsView"/> class.
/// </summary>
[ImportingConstructor]
public SettingsView()
{
InitializeComponent();
}

/// <summary>
/// Sets the view model using MEF import.
/// </summary>
[Import]
public SettingsViewModel ViewModel
{
set
{
this.DataContext = value;
}
}
}
}

[/code]

You can see that there is nothing to unit test here.  Both the constructor and the single write-only property are handled by MEF importing.  MEF is used through out the solution to matching views to view models in this fashion.  The data context for each view’s binding is imported using MEF Import attribute on the ViewModel property that is setup for each view.  This plumbing is part of setting up each view and cannot be overlooked.  It is also possible to use Unity Dependency Injection with PRISM and many people do.  Also it is possible to use PRISM with MEF for modularity and Unity for dependency injection, together but that is a debate for another time.

Unit Testing the View Models

So when the time comes to unit test my ui modules I previously have dreaded it, not sure why, mainly because it just hasn’t come naturally to me.  Usually when writing unit tests for, let us say an application service, it just flows.  I am able to easily see what should be tested and fairly easily write the tests.  The only issues being making sure that I am able to mock my dependencies easily.  But for view models it isn’t as simple.  I am never sure just what should be tested and how to test it.  So let us look at some examples.  First, here is a view model for one of my settings views:

[code language=”csharp”]

[Export]
[HasSelfValidation]
public class VolumeSettingsViewModel : BaseSettingsViewModel<VolumeSettingsViewModel>
{
private decimal _macroMinimumFlushVolume;

private decimal _macroMinimumPrimeVolume;

private decimal _manifoldMinimumFlushVolume;

private decimal _microMinimumFlushVolume;

private decimal _microMinimumPrimeVolume;

/// <summary>
/// Initializes a new instance of the <see cref="VolumeSettingsViewModel"/> class.
/// </summary>
/// <param name="serviceAggregator">The service aggregator.</param>
/// <param name="settingsController">The settings controller.</param>
[ImportingConstructor]
public VolumeSettingsViewModel(IServiceAggregator serviceAggregator, ISettingsController settingsController)
: base(serviceAggregator)
{
DisplayName = Resources.Properties.Resources.VolumeSettingsView_DisplayName;

settingsController.RegisterSettingsViewModel(this);

RegisterProperties();
Initialize();
}

[RangeValidator(typeof(decimal), Constants.MinMacroFlushRange, RangeBoundaryType.Inclusive, Constants.MaxMacroFlushRange,
RangeBoundaryType.Inclusive, MessageTemplateResourceName = "VolumeView_RangeErrorMessage",
MessageTemplateResourceType = typeof(Res))]
public decimal MacroMinimumFlushVolume
{
get
{
return _macroMinimumFlushVolume;
}
set
{
if (value.Equals(_macroMinimumFlushVolume))
{
return;
}
_macroMinimumFlushVolume = value;
RaisePropertyChanged(() => MacroMinimumFlushVolume);
IsDirty = true;
}
}

[RangeValidator(typeof(decimal), Constants.MinMacroPrimeRange, RangeBoundaryType.Inclusive, Constants.MaxMacroPrimeRange,
RangeBoundaryType.Inclusive, MessageTemplateResourceName = "VolumeSettingsView_RangeErrorMessage",
MessageTemplateResourceType = typeof(Res))]
public decimal MacroMinimumPrimeVolume
{
get
{
return _macroMinimumPrimeVolume;
}
set
{
if (value.Equals(_macroMinimumPrimeVolume))
{
return;
}
_macroMinimumPrimeVolume = value;
RaisePropertyChanged(() => MacroMinimumPrimeVolume);
IsDirty = true;
}
}

[RangeValidator(typeof(decimal), Constants.MinManifoldFlushRange, RangeBoundaryType.Inclusive, Constants.MaxManifoldFlushRange,
RangeBoundaryType.Inclusive, MessageTemplateResourceName = "VolumeSettingsView_RangeErrorMessage",
MessageTemplateResourceType = typeof(Res))]
public decimal ManifoldMinimumFlushVolume
{
get
{
return _manifoldMinimumFlushVolume;
}
set
{
if (value.Equals(_manifoldMinimumFlushVolume))
{
return;
}
_manifoldMinimumFlushVolume = value;
RaisePropertyChanged(() => ManifoldMinimumFlushVolume);
IsDirty = true;
}
}

[RangeValidator(typeof(decimal), Constants.MinMicroFlushRange, RangeBoundaryType.Inclusive, Constants.MaxMicroFlushRange,
RangeBoundaryType.Inclusive, MessageTemplateResourceName = "VolumeSettingsView_RangeErrorMessage",
MessageTemplateResourceType = typeof(Res))]
public decimal MicroMinimumFlushVolume
{
get
{
return _microMinimumFlushVolume;
}
set
{
if (value.Equals(_microMinimumFlushVolume))
{
return;
}
_microMinimumFlushVolume = value;
RaisePropertyChanged(() => MicroMinimumFlushVolume);
IsDirty = true;
}
}

[RangeValidator(typeof(decimal), Constants.MinMicroPrimeRange, RangeBoundaryType.Inclusive, Constants.MaxMicroPrimeRange,
RangeBoundaryType.Inclusive, MessageTemplateResourceName = "VolumeSettingsView_RangeErrorMessage",
MessageTemplateResourceType = typeof(Res))]
public decimal MicroMinimumPrimeVolume
{
get
{
return _microMinimumPrimeVolume;
}
set
{
if (value.Equals(_microMinimumPrimeVolume))
{
return;
}
_microMinimumPrimeVolume = value;
RaisePropertyChanged(() => MicroMinimumPrimeVolume);
IsDirty = true;
}
}

protected override sealed void Initialize()
{
base.Initialize();
}

protected override sealed void RegisterProperties()
{
RegisterProperty(() => MicroMinimumPrimeVolume);
RegisterProperty(() => MacroMinimumPrimeVolume);
RegisterProperty(() => MacroMinimumFlushVolume);
RegisterProperty(() => MicroMinimumFlushVolume);
RegisterProperty(() => ManifoldMinimumFlushVolume);
}

#endregion
}

[/code]

This is a new view called VolumeSettingsView that allows the user to setup some minimum volume amounts for a dispensing device.  I have altered it a little bit in order to simplify and somewhat obscure its real purpose.  I did not want to have to completely write a new view and view model so this is from a work project but as I said, I have kind of dumbed it down a bit.  But as you can see from the view model code, there are 5 values for the user to edit and they are represented by properties on the view model.  There is also some plumbing code in the form of the BaseSettingsViewModel.  The base class implements the connection to the service class that provides and stores these values.  I will not go into how it all works, but generally speaking it uses reflection to pull setters and getters for both the view model and the target service so that the updating of values to/from the service is done by the base class and can be re-used for all of the settings view models.  Pretty sweet.  The last method, RegisterProperties is what sets this all up.  The lambda expressions passed in are used to reflect the getters and setters so that it can all be automated.  Anyways, lets get to some unit tests.  I never have seen the need to unit test C# and .NET library code as that is handled by the authors at Microsoft, so no need to exercise the getters and setters for the view model properties, so let us start with the constructor.  That is usually my first point of entry when I am starting my unit tests.  So,

What does the constructor do?  Let us look at the code:

[code language=”csharp”]

/// <summary>
/// Initializes a new instance of the <see cref="VolumeSettingsViewModel"/> class.
/// </summary>
/// <param name="serviceAggregator">The service aggregator.</param>
/// <param name="settingsController">The settings controller.</param>
[ImportingConstructor]
public VolumeSettingsViewModel(IServiceAggregator serviceAggregator, ISettingsController settingsController)
: base(serviceAggregator)
{
DisplayName = Resources.Properties.Resources.PrimeFlushSettingsView_DisplayName;

settingsController.RegisterSettingsViewModel(this);

RegisterProperties();
Initialize();
}

[/code]

a. First we set a DisplayName property from a resource string.  This is a base class property that happens to be the text for the tab item, but it needs to be set, so we can test that.

b.  Second, a method on the settings controller class is called to register the view model with the controller.  In this particular implementation I used a controller class for the module.  I do not always do this, only when necessary.

In this case, because the settings are spread across several views, I needed a place to coordinate the saving and initialization and other things for all of the settings in one place.  So, I added a controller.  The settings controller handles the save button for all of the settings tabs together.  It checks with each one to see if the values have changed and are valid, so that if the user clicks okay on the confirmation dialog, the save can be performed on all settings view models.  That is where the register method comes in.  Accepting any instance of IBaseSettingsViewModel, it can manage a list of all of them.  Without, I might add, any of the individuals knowing about each other.  One of the caveats that must be dealt with when using this setup is that due to the loosely coupled views and view models, and due to the fact that they are all imported using MEF, no one class knows about any of the others.  There wasn’t anywhere to manage all of the separate view models, hence a controller class.  The controller is made aware of the view model only when the view model says “Here I am” by registering.  This maintains the loose coupling.  I could remove any one of the settings views and its view model and the module would still perform with those that remain.  The controller doesn’t care how many view models register with it and will handle them all the same.  Similarly, I could add a new settings tab view/viewmodel and as long as it implements the base interface and registers with the controller, then what ever settings values it exposes can become part of the validation and saving process when the user hits the save button.

So now we can write tests for the constructor.  We will test that the display name property is set and that the view model registers with the controller.  Makes sense to me anyways…

[code language=”csharp”]

[TestClass]
public class VolumeSettingsViewModelTests
{
private readonly MockServices _mockServices = new MockServices();

private readonly Mock<ISettingsController> _mockSettingsController = new Mock<ISettingsController>();

[TestMethod]
public void TestVolumeSettingsViewModelConstructorInitializesMembers()
{
// Arrangements
_mockSettingsController.SetupAllProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object);

// Assertions
Assert.IsNotNull(cut);
Assert.IsFalse(cut.DisplayName.IsNullOrEmpty());
_mockSettingsController.Verify(c => c.RegisterSettingsViewModel(cut), Times.Once());
}
}

[/code]

A couple of things to note here.  The MockServices type is in a separate unit testing common library that holds any custom mocks that are used over multiple unit tests.  MockServices is a mock of all of the application services, including a custom event aggregator mock.  The other services are mocked using Moq which we use at work for all of our mocking needs.  It works well, is easy to use and I can say that I like it very much.  I use mocks of the application services layer so much that I wrote a class that collects them all and creates mocks of them all. Each mocked service is exposed in two ways from the MockServices class.  First as a property of the mock itself, i.e. _mockServices.DialogServiceMock, which allows me to make setup and verify calls on the mock of IDialogService.  Second as the Object needed for the service for use in passing as a parameter to constructors, etc.  For example, if I needed a mock of the dialog service to construct a view model in a unit test I could pass in _mockServices.Aggregator.DialogService and that would not pass the mock but rather the .Object property of the mock, which when using Moq is how you get the instance of the type you are mocking.

So we have tested our view model constructor by asserting that it sets a valid string to the DisplayName property and we have tested that it registered itself with the controller by using the Verfiy method on our mock of the controller (line 20).  If a verify call is not successful, a MoqException is thrown which fails the test.

2. What else can we test for?  What else does this view model do?  Well part of the way my settings models work is by registering the properties that are fed by a service, as I explained is accomplished in the BaseSettingViewModel class.  So we can test that this has occurred and is working correctly.

a. We need to setup our mock of the target service that feeds these settings values (in this case it happens to be called ConfigurationService).

b. We need to then change the values of the settings on our view model instance, so that we can…

c. Check that the values were updated on the target service successfully.

Here is the code for that unit test:

[code language=”csharp”]

[TestMethod]
public void TestVolumeSettingsViewModelRegistersPropertiesWithService()
{
// Arrangements
const decimal TestVolumeValue = 20.5M;
_mockServices.ConfigurationServiceMock.SetupProperty(c => c.MacroMinimumFlushVolume);
_mockServices.ConfigurationServiceMock.SetupProperty(c => c.MicroMinimumFlushVolume);
_mockServices.ConfigurationServiceMock.SetupProperty(c => c.ManifoldMinimumFlushVolume);
_mockServices.ConfigurationServiceMock.SetupProperty(c => c.MacroMinimumPrimeVolume);
_mockServices.ConfigurationServiceMock.SetupProperty(c => c.MicroMinimumPrimeVolume);
_mockServices.Aggregator.ConfigurationService.MacroMinimumFlushVolume = 0;
_mockServices.Aggregator.ConfigurationService.MicroMinimumFlushVolume = 0;
_mockServices.Aggregator.ConfigurationService.ManifoldMinimumFlushVolume = 0;
_mockServices.Aggregator.ConfigurationService.MacroMinimumPrimeVolume = 0;
_mockServices.Aggregator.ConfigurationService.MicroMinimumPrimeVolume = 0;

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MacroMinimumFlushVolume = TestVolumeValue,
MicroMinimumFlushVolume = TestVolumeValue,
ManifoldMinimumFlushVolume = TestVolumeValue,
MacroMinimumPrimeVolume = TestVolumeValue,
MicroMinimumPrimeVolume = TestVolumeValue
};
cut.SaveChanges();

// Assertions
Assert.AreEqual(
_mockServices.Aggregator.ConfigurationService.MacroMinimumFlushVolume, cut.MacroMinimumFlushVolume);
Assert.AreEqual(
_mockServices.Aggregator.ConfigurationService.MicroMinimumFlushVolume, cut.MicroMinimumFlushVolume);
Assert.AreEqual(
_mockServices.Aggregator.ConfigurationService.ManifoldMinimumFlushVolume, cut.ManifoldMinimumFlushVolume);
Assert.AreEqual(
_mockServices.Aggregator.ConfigurationService.MacroMinimumPrimeVolume, cut.MacroMinimumPrimeVolume);
Assert.AreEqual(
_mockServices.Aggregator.ConfigurationService.MicroMinimumPrimeVolume, cut.MicroMinimumPrimeVolume);
}

[/code]

This code should be fairly self explanatory, with the exception of maybe the moq specific code, but a quick look at the Moq QuickStart should clear up any confusion.  Basically I have just setup the five properties on the ConfigurationService mock and then set a new value to each, then asserted that new value (set on the view model) on the service property.  Note that the setup for the properties on the ConfigurationService only sets it so that any value set to that property will be returned by the mock.  Kind of like saying, “Okay, setup this property with a get and set”.  I also set all of the properties to a default value of 0.

So, now I have tested the underlying functionality of the view model’s link to the configuration service.  What else is there to test?

3. If you remember from the listing of the VolumeSettingsViewModel you might remember that the volume properties have some validation attributes on them, and these happened to be tied to some more functionality from the BaseSettingsViewModel class that sets a HasErrors flag if the validation fails.  So, that should probably be tested too.

a. There is a RangeValidator attribute on each volume property, from the Ent. Lib Validation Block which we use for validation of domain models.

We also use it for validation of applicable view model properties.  There is in fact some builtin wiring that sets up the validation error messages for the user in the xaml as well.  This is done using a custom control template for textboxes.

b. The range validator has an upper bound limit and a lower bound limit.  I need to test both upper and lower, for each of the 5 volume properties.  So ten tests in all, one for each situation, for each property.

Here is the code for those tests:

[code language=”csharp”]

[TestMethod]
public void TestVolumeSettingsViewModelValidationLowerRangeMacroFlush()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MinMacroFlushRange) – 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MacroMinimumFlushVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationLowerRangeMacroPrime()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MinMacroPrimeRange) – 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MacroMinimumPrimeVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationLowerRangeManifoldFlush()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MinManifoldFlushRange) – 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
ManifoldMinimumFlushVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationLowerRangeMicroFlush()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MinMicroFlushRange) – 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MicroMinimumFlushVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationLowerRangeMicroPrime()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MinMicroPrimeRange) – 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MicroMinimumPrimeVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationUpperRangeMacroFlush()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MaxMacroFlushRange) + 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MacroMinimumFlushVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationUpperRangeMacroPrime()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MaxMacroPrimeRange) + 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MacroMinimumPrimeVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationUpperRangeManifoldFlush()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MaxManifoldFlushRange) + 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
ManifoldMinimumFlushVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[TestMethod]
public void TestVolumeSettingsViewModelValidationUpperRangeMicroFlush()
{
// Arrangements
var testVolumeValue = Convert.ToDecimal(Constants.MaxMicroFlushRange) + 1;
SetupConfigurationServiceProperties();

// Actions
var cut = new VolumeSettingsViewModel(_mockServices.Aggregator, _mockSettingsController.Object)
{
MicroMinimumFlushVolume = testVolumeValue,
};
cut.Validate();

// Assertions
Assert.IsTrue(cut.HasErrors);
}

[/code]

These tests are all very similar, varying only in which volume property is tested and whether testing the lower limit or the upper.  Each test uses the constant value that is used in the actual RangeValidator and either adds or subtracts 1 to come up with a value that is outside the limits.  Then that invalid value is set to the property on the view model.  The validate method is called and then we assert that the HasErrors flag is correctly set showing the invalid value.

Summing Up…

Well, I guess that is a pretty good glimpse at what I went through to get these view models tested.  I just wanted to provide some real world examples into how to come up with what unit tests to write for a view model.  It is something that doesn’t come as easily for me as other unit testing and I have never really found a blow by blow set of examples like what I have hopefully provided here.  In other words, I wish I would have found an article like this when I first started with PRISM and MVVM, that would have helped me with my unit testing.

Certainly nothing earth shattering, and in fact, these examples are pretty simple, but I wanted to convey the through process and the “on the ground” example of some unit testing for view models.  I could go through the rest of the view models but as they are all settings view models, the subsequent test are all very similar, as is the process behind coming up with them.

I hope that this helps someone.  And please offer some feedback if you have experience in this and can offer some insight.  I am still very much looking to improve my unit testing process and technique and all input would be appreciated.

VS 2012 Code Mapping!

This is just a quick note to extoll the smoothness of the new Code Mapping feature in Visual Studio 2012. I am working on some of the model classes for the Whistle project I mentioned in a previous post and I actually found myself wanting to see a graphical representation of the classes I had been adding. I added several at once no real plan in mind for the final design, just sort of shooting from the hip if you will. Therefore, the short video I had seen after installing the VS 2012 Update 1 package that had afforded me a brief overview of the Code Map feature definitely made it easy to try it out.
I was able to produce this interactive code map graphic in no more than seconds, maybe 30 or even 40. That includes rearranging what was produced by default after selecting “Show on Code Map” and dragging over a few files from Solution Explorer. The map is interactive with information about the relationships if relevant, and offers expandable class details info, and more I am sure, I just did some curiosity clicking.

Picture of the VS 2012  code mapping feature.
Took only a few seconds to build this map graphic.

Allowing me to so quickly switch to working with the classes visually is enough of a reason for me to want to spend some time playing with this new feature. Also, the video I mentioned above is at a link on the Start Page after you install the Update 1. It was the first of three at the top, under the heading “New in Visual Studio Ultimate 2012 Update 1:” and was only 3 or 3 and 1/2 minutes. The title was “Understanding complex code with Code Map.” If anyone does happen across this, I would greatly appreciate a quick comment about your experiences with this new feature or any tip about how you may have used it.

C# Extension Method and Lambda Expressions

Recently I have been trying to learn more about the new language features in C# 3.0, and I have enjoyed what I have found thus far.  Especially both the var keyword and extension methods, but I had yet to really implement anything using lambdas.  That is until today…

One of the things I have done with extension methods was to implement some really sweet method argument validation stuff.  I had read several related blog entries regarding this subject and had whipped up a variation [actually just a much smaller set of what they had already come up with as my needs were much less] of their ideas for use in a project I am working on [and likely in future projects].   And, as it turns out, this same bit of features afforded me the opportunity to check out lambda expressions as well, and to hopefully this time add something of value to build on their work instead of just reusing it.

Okay so the scene is set, with me at my desk at work, coding a unit test for what I hope will be a new feature on my current project [dynamically executed reports from xml definition files, like rdl but much much simpler]…

I was about to use the argument extension methods to validate an integer that I needed to be in a certain range and it occured to me how nice it would be if I could just pass in an expression that evaluated to a boolean result similar to what I would do if I was writing in javascript.  Yeah, that would be extra nice!  So, off I went back to GOG to do some research on passing an expression as an argument to a function in C#.  My research led me straight to lambda expressions and exactly what I needed to make my new extension method work.

My goal was to be able to implement something like the following psuedo-code:

[sourcecode language=’csharp’]
public void MyFunction(int myInt)
{
    RequireThat(myInt).MeetsCriteria(“myInt > 0”);
}
[/sourcecode]

Thus being able to use some very smooth and descriptive code to validate my integer argument before using it in the function, or atleast something as close to that effect as I could get.

Well lambda expressions were exactly the ticket, specifically the Func<T, TResult> delegate type.  Which basically allows me to pass a method that accepts one parameter of type T and returns a result of type TResult as a parameter to another method, without defining a custom delegate type of my own.  A kinda anonymous delegate type construct if you will.  Lambda expressions use this type as an arg for the Expression<T>(Func<T, TResult) type constructor.   I have done some of this preliminary reading on Expression Trees and such and it is heady stuff, but interesting none the less.  I look forward to someday being able to apply it to a real world problem.  

But today I was able to apply lambdas to my real world problem like so:

I needed an extension method for my Generic argument wrapper that would allow me to pass in a simple expression predicate with which to validate the argument.  And here is what I came up with:

Code for MeetsCriteria extension method.
Code for MeetsCriteria extension method.

Now this code allows me to pass in a lambda expression that I wish to use to validate an integer argument for my method [or any integer for that matter].  This method was added to my existing argument validation extension methods setup as described in a previous post, already linked to a couple of times above, so it follows similar usage syntax, as such:

myIntArg.RequireThat("myIntArg").MeetsCriteria(...);

I also added a unit test for this new method into my existing test project for the rest of my validation extension methods, and so I will use that test method to show you a contextual usage of MeetsCriteria…

My unit test for MeetsCriteria method.  Testing that 21 is between 20 and 22.
My unit test for MeetsCriteria method. Testing that 21 is between 20 and 22.

So, now I have actually used lambdas in a project at work, I am so very happy with myself.  And my quest to conquer C# 3.0 features continues… J

Argument Validation using C# 3.0 extension methods

 After some research into reusable arg validation ideas on GOG (good ole google) I have found something that, after some simplification of course, will serve the projects meager argument validation needs. Actually this is a super cool trick that we can reuse any number of places from here on, if we so desire.  Here are the original posts that I read and have taken ideas from, particularly Roger Alsings articles, much thanks to him.  This technique is, IMHO, a nice way to showcase how to combine some of C#’s new features, specifically Generics from C# 2.0 and Extension methods from C# 3.0, into a nice solution to a frequent problem.  

http://rogeralsing.com/2008/05/10/followup-how-to-validate-a-methods-arguments/
http://weblogs.asp.net/fredriknormen/archive/2008/05/08/how-to-validate-a-method-s-arguments.aspx
http://www.puzzleframework.com/wikiengine/WikiPageViewer.aspx?ID=78

Using these posts and the code from a much larger api at the puzzle framework address in the quote above, i have assembled a smaller set of argument validation methods.  Roger Alsing’s puzzle framework has a full compliment of these validation methods if you are interested.  I, on the other hand swiped just a couple of his and added a couple of my own, but am using the same technique to acheive a fluent interface and also the very ingenius idea he had of using a wrapper class for the extension methods rather than extending each .NET type on its own.  Very nice work by him.  This article is simply an effort to explain how I used these articles to put together a much smaller set of validation methods for my own use in a project.  Hopefully it explains things clearly and pays sufficient homage to the ideas originator.

 

The basic premise is that now with generics and extension methods features of C# we are able to add functionality to types/classes. In this case all types, for the purpose of validating method arguments. The articles above explore this in a progressive fashion: First presenting the idea of an ArgumentHelper class that would have lots of overloads for validating various C# types, i.e. int, string, double, etc. Under this scheme you would need a separate method for each type of validation for each type. Such as:

[sourcecode language=’csharp’]
public void RequireNotNull(int arg, string argName);
public void RequireNotNull(string arg, string argName);
public void RequireNotNull(DateTime arg, string argName);

[/sourcecode]

This is not a bad idea, and certainly is better than writing a multiline if statement for each argument in each method in your project. Second Idea: was to use extension methods to facilitate usage syntax like:

[sourcecode language=’csharp’]
public void MyMethod(int argument1, string argument2)
{
    // validate args
    argument1.RequireInRange(argument1, 0, 10, “argument1”);
    argument2.RequireNotNull(argument2, “argument2”);
}
[/sourcecode]

Now this is starting to look pretty smooth, however we go one step further, combining the new features of Generics(C# 2.0) and Extension methods (C# 3.0) to get something that is SUPER smooth. The idea, which was of course new to me, is to a) create a generic type for argmuments. I used one similar to theirs, basically just a container for name and value of an argument the value being the arg itself of the type “T” as defined by the generic. Then b) use extension methods to add validation methods to this generic class, thus making them available to any type. Here is my generic argument container class that is the one extended:

[sourcecode language=’csharp’]
public class ArgumentEx
{
public T Value { get; set; }
public string Name { get; set; }
public ArgumentEx(T value, string name)
{
    this.Value = value;
    this.Name = name;
}   
public static implicit operator T(ArgumentEx arg)
{
return arg.Value;
}
}
[/sourcecode]

This class simply wraps an argument with a generic container in essence. We set the default operator to return the arg itself (the “Value” member) and create a simple ctor. Now instead of having to write an extension method for each type we want to be able to validate (int, string, etc.) we just write one extension method for this class. First we write an extension method for the generic T type of our generic class and that will give us coverage of all types and this will always return us an instance of our new ArgumentEx type:

[sourcecode language=’csharp’]
public static class ValidatorExtensions
{
    public static ArgumentEx RequireThat(
this T arg, string name)

    {
        return new ArgumentEx(arg, name);
    }
}
[/sourcecode]

Now we can call this RequireThat method from any argument we pass in to any method and we will get back our ArgumentEx class which we have extended with validation methods such as this:

[sourcecode language='csharp']
[DebuggerHidden]
public static ArgumentEx NotNull(
this ArgumentEx arg) where T : class
{           
    if (arg.Value == null)
        throw new ArgumentNullException(arg.Name);
    return arg;     // for fluency
}
[/sourcecode]

This method extends the ArgumentEx type rather than the generic T type so we have all of our extension methods hanging off of the wrapper class. This setup is a touch abstract but it allows us to do super pretty things like this:

[sourcecode language='csharp']
public ReportInfo(string pathToXmlFile)
: base(null, null)         
{
    // validate args
    pathToXmlFile.RequireThat("pathToXmlFile").IsNotNull();           
}
[/sourcecode]

not bad in the way of readability and extensibility too. Because the extension methods return the arg instance every time you can chain calls as well.

 

Below is the class diagram for the validation/argument extensions.  There are a few string extensions too added for convenience...

 

Class diagram for the validation extension classes.
Class diagram for the validation extension classes.

 

 

 

And here is a screenshot of the unit tests all green and pretty!

 

A screenshot of the pretty green unit test results!
A screenshot of the pretty green unit test results!

 

 

 

So now I have an easy to use and further extensible system for validating method arguments with out having to write if/throw constructs over and over inside of each method.  This promotes better code because the easier it is to validate my arguments the more likely it is that I will do a thorough job of it.

Google Base, Reporting Xml, and VS Unit Testing

I have been working on an interesting project here at work.  I had previously been working on some fixes for a windows service (written in C#) that uploaded our catalog items to Google Base, based on some logging and comparison diffs, every fifteen minutes if there were new items or updates to items.  But, with that seemingly on its way now, I was assigned this new project.  Basically I am working on a system that will allow the definition of sql queries, or data “views” via an XML schema.  Yes, I know there is already RDL for SQL Reporting Services, but that is not what they want.  They want a much, much simpler setup that will make it easier for a developer on the team to make changes to, or add a new report, by editing the XML  definition file.

So, off I go.  I started with the whiteboard notes that were put up during my initial meeting about this, and the sample XML there-in, and have tried to keep it as simple as possible.  I am using classes for each logical report entity, such as:  Report, Query, Column, Parameter, etc.  I am also using the VS unit testing framework for this project, which is something I hadn’t done previously, but wanted to.  Let me qualify that by saying up front that I am not using TDD strictly speaking.  But I am writing tests for code, classes and methods, as I go.  I must say I am quickly becoming hooked on the idea of unit testing everything, whether you are designing with TDD or not, it just makes sense, and it does honestly help with design decisions.  By testing your code as you go or before hand you get a quick look at how it will be called, which in my case where I am developing what hopes to be an api of sorts that will be extended and re-used often is a great benefit.   Continue reading