Category Archives: Programming

Creating a SpecFlow code generation plugin

Over the last few months I’ve been helping develop an Appium/WinAppDriver framework (or library if you prefer) to allow one of the application to look to move one of my client’s application away from CodedUI (support is being phased out for this).

One of the problem I had is, I wanted to be able to put text into the Windows Clipboard and paste it into an various edit controls. The pasting made things slightly quicker but also, more importantly, bypassed some control’s autocomplete which occasionally messes up using SendKeys.

The problem is that the clipboard uses OLE and NUnit complains that it needs to be running in an STA.

To fix this, SpecFlow classes are partial so we can create new classes within another file with the same classname (and mark as partial) and namespace and then add the NUnit require attribute as below

[NUnit.Framework.Apartment(System.Threading.ApartmentState.STA)]
public partial class CalculatorFeature
{
}

This is all well and good. It’s hardly a big deal, but we have hundreds of classes and it’s just more hassle, remembering each time to do this, or you run the tests and when it hits a Paste from the Clipboard, it fails, wasting a lot of time before you’re reminded you need to create the partial class.

SpecFlow has the ability to intercept parameters passed into our steps, it has tags and hooks which allow you to customize behaviour and it also comes with a way to interact with the code generation process which we can use to solve this issue and generate the required attributes in the generated code.

The easiest way to get started is follow the steps below, although if you prefer, the code I’m presenting here is available on my PutridParrot.SpecFlow.NUnitSta GitHub repo., so you can bypass this post and go straight the code for this article if you prefer.

  • Grab the zip or clone the repo to get the following GenerateOnlyPlugin
  • You may want to update SampleGeneratorPlugin.csproj to
    <TargetFrameworks>net472;netcoreapp3.1</TargetFrameworks>
    

    I would keep to these two frameworks to begin with, as we have a few other places to change and it’s better to get something working before we start messing with the rest of the build properties etc.

  • In the build folder edit the .targets file to reflect the Core and !Core frameworks, i.e.
    <_SampleGeneratorPluginFramework Condition=" '$(MSBuildRuntimeType)' == 'Core'">netcoreapp3.1</_SampleGeneratorPluginFramework>
    <_SampleGeneratorPluginFramework Condition=" '$(MSBuildRuntimeType)' != 'Core'">net472</_SampleGeneratorPluginFramework>
    

    Again I’ve left _SampleGeneratorPluginFramework for now as I just want to get things working.

  • Next go to the .nuspec file and change the file location at the bottom of this file, i.e.
    <file src="bin\$config$\net472\PutridParrot.SpecFlow.NUnitSta.*" target="build\net472"/>
    <file src="bin\$config$\netcoreapp3.1\PutridParrot.SpecFlow.NUnitSta.dll" target="build\netcoreapp3.1"/>
    <file src="bin\$config$\netcoreapp3.1\PutridParrot.SpecFlow.NUnitSta.pdb" target="build\netcoreapp3.1"/>
    
  • Now go and change the name of the solution, the project names and the assembly namespace if you’d like to. Ofcourse this also means changing the PutridParrot.SpecFlow.NUnitSta in the above to your assembly name.

At this point you have a SpecFlow plugin which does nothing, but builds to a NuGet package and in your application you can set up your nuget.config with a local package pointing to the build from this plugin. Something like

<packageSources>
  <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
  <add key="Local" value="F:\Dev\PutridParrot.SpecFlow.NUnitSta\PutridParrot.SpecFlow.NUnitSta\bin\Debug"/>
</packageSources>

Obviously change the Local package repository value to the location of your package builds.

Now if you like, you can create a default SpecFlow library using the default SpecFlow templates. Ensure the SpecFlow.NUnit version is compatible with your plugin (so you may need to update the package from the template one’s). Finally just add the package you built and then build your SpecFlow test library.

If all went well, nothing will have happened, or more importantly, no errors will be displayed.

Back to our Plugin, thankfully I found some code to demonstrated adding global:: to the NUnit attributes on GitHub, so my thanks to joebuschmann.

  • Create yourself a class, mine’s NUnit3StaGeneratorProvider
  • This should implement the interface IUnitTestGeneratorProvider
  • The constructor should look like this (along with the readonly field)
    private readonly IUnitTestGeneratorProvider _unitTestGeneratorProvider;
    
    public NUnit3StaGeneratorProvider(CodeDomHelper codeDomHelper)
    {
       _unitTestGeneratorProvider = new NUnit3TestGeneratorProvider(codeDomHelper);
    }
    
  • We’re only interested in the SetTestClass, which looks like this
    public void SetTestClass(TestClassGenerationContext generationContext, string featureTitle, string featureDescription)
    {
       _unitTestGeneratorProvider.SetTestClass(generationContext, featureTitle, featureDescription);
    
       var codeFieldReference = new CodeFieldReferenceExpression(
          new CodeTypeReferenceExpression(typeof(ApartmentState)), "STA");
    
       var codeAttributeDeclaration =
          new CodeAttributeDeclaration("NUnit.Framework.Apartment", new CodeAttributeArgument(codeFieldReference));
             generationContext.TestClass.CustomAttributes.Add(codeAttributeDeclaration);
    }
    

    All other methods will just have calls to the _unitTestGeneratorProvider method that matches their method name.

  • We cannot actually use this until we register out new class with the generator plugins, so in your Plugin class, mine’s NUnitStaPlugin, change the Initialize to look like this
    public void Initialize(GeneratorPluginEvents generatorPluginEvents, 
       GeneratorPluginParameters generatorPluginParameters,
       UnitTestProviderConfiguration unitTestProviderConfiguration)
    {
       generatorPluginEvents.CustomizeDependencies += (sender, args) =>
       {
          args.ObjectContainer
             .RegisterTypeAs<NUnit3StaGeneratorProvider, IUnitTestGeneratorProvider>();
       };
    }
    
  • If you changed the name of your plugin class ensure the assembly:GeneratorPlugin reflects this new name, the solution will fail to build if you haven’t updated this anyway.

Once all these things are completed, you can build your NuGet package again. It might be worth incrementing the version and then update in your SpecFlow test class library. Rebuild that and the generated .feature.cs file should have classes with the [NUnit.Framework.Apartment(System.Threading.ApartmentState.STA)] attribute now. No more writing partial classes by hand.

This plugin is very simple, all we’re really doing is creating a really minimal implementation of IUnitTestGeneratorProvider which just adds an attribute to a TestClass and we registered this with the GeneratorPluginEvents, there’s a lot more why could potentially do.

Whilst this was very simple in the end. The main issues I had previously with this are that we need to either copy/clone or handle these build props and targets as well as use .nuspec to get our project packaged in a way that works with SpecFlow.

Unit testing your MAUI project

Note: I found this didn’t work correctly on Visual Studio for Mac, I’ll update the post further if I do get it working.

This post is pretty much a duplicate of Adding xUnit Test to your .NET MAUI Project but just simplified for me to quickly repeat the steps which allow me to write unit tests against my MAUI project code.

So, you want to unit test some code in your MAUI project. It’s not quite as simple as just creating a test project then referencing the MAUI project. Here are the steps to create an NUnit test project with .NET 7 (as my MAUI project has been updated to .NET 7).

  • Add a new NUnit Test Project to the solution via right mouse click on the solution, Add | Project and select NUnit Test Project
  • Open the MAUI project (csproj) file and prepend the net7.0 to the TargetFrameworks so it looks like this
    <TargetFrameworks>net7.0;net7.0-android;net7.0-ios;net7.0-maccatalyst</TargetFrameworks>
    
  • Replace <OutputType>Exe</OutputType> with the following
    <OutputType Condition="'$(TargetFramework)' != 'net7.0'">Exe</OutputType>
    

    Yes, this is TargetFramework singular. You may need to reload the project.

  • Now in your unit test project you can reference this MAUI project and write your tests

So, why did we carry out these steps?

Our test project was targeting .NET 7.0 but our MAUI project was targeting different platform implementations of the .NET 7 frameworks, i.e those for Android etc. We need the MAUI project to build a .NET 7.0 compatible version hence added the net7.0 to the TargetFrameworks.

The change to add the OutputType ensures that we only build an EXE output for those other frameworks, and therefore for .NET 7.0 we’ll have a DLL to reference instead in our tests.

Now we can build and run our unit tests.

A few tips and tricks for using Infragistics XamDataGrid

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

I’m working on a project using the XamDataGrid. I’ve used the UltraWinGrid by Infragistics in the past but that doesn’t help at all when moving code from Windows Formds to WPF. So here’s a list of a few commonly required features and how to do them using the XamDataGrid.

Note: this post only refers to using version 12.2

Grid lines

Problem: By default there are no grid lines on the XamDataGrid.

Solution: In your ResourceDictionary (within Generic.xaml or wherever you prefer) add the following

<Style TargetType="{x:Type igDP:CellValuePresenter}">
   <Setter Property="BorderThickness" Value="0,0,1,1" />
   <Setter Property="BorderBrush" Value="{x:Static SystemColors.ControlLightBrush}" />
</Style>

Obviously replace the BorderBrush colour with your preferred colour.

Remove the group by area

Problem: I want to remove the group by section from the XamDataGrid.

Solution: In your ResourceDictionary (within Generic.xaml or wherever you prefer) add the following

<Style x:Key="IceGrid" TargetType="igDP:XamDataGrid">
   <Setter Property="GroupByAreaLocation" Value="None" />
</Style>

don’t forget to apply the style to your grid, i.e.

<dp:XamDataGrid Style="{StaticResource IceGrid}" DataSource="{Binding Details}">
   <!- Your grid code -->
</dp:XamDataGrid>

Column formatting

Problem: We want to change the numerical formatting for a column

Solution: We can set the EditorStyle for a field (editor doesn’t mean it will make the field editable)

<dp:XamDataGrid.FieldLayouts>
   <dp:FieldLayout>
      <dp:FieldLayout.Fields>
         <dp:Field Name="fee" Label="Fee" Width="80">
            <dp:Field.Settings>
               <dp:FieldSettings>
                  <dp:FieldSettings.EditorStyle>
                     <Style TargetType="{x:Type editors:XamNumericEditor}">
                        <Setter Property="Format" Value="0.####" />
                     </Style>
                  </dp:FieldSettings.EditorStyle>
               </dp:FieldSettings>
           </dp:Field.Settings>
        </dp:Field>         
      </dp:FieldLayout.Fields>
   </dp:FieldLayout>
</dp:XamDataGrid.FieldLayouts>

This code creates a field named fee and with the label Fee and the editor is set to only display decimal places if they actually exist.

As we’re defining the fields you’ll need to turn off auto generation of fields, as per

<dp:XamDataGrid.FieldLayoutSettings>
   <dp:FieldLayoutSettings AutoGenerateFields="False" />
</dp:XamDataGrid.FieldLayoutSettings>

First Chance Exceptions can be more important than you might think

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

You’ll often see First Chance exceptions in the output window of Visual Studio without them actually causing any problems with your application, so what are they ?

A first chance exception is usually associated with debugging an application using Visual Studio, but they can occur at runtime in release builds as well.

A first chance exception occurs whenever an exception occurs. The exception is thrown at which point .NET searches for a handler (a catch) up the call stack. If a catch is found then .NET passes control to the catch handler code. So in this instance, let’s say we see a first chance exception which is caught in some library code. Then, whilst debugging, we’ll see the message that a first chance exception occurred, but it won’t cause an exception to halt an application because it’s caught. On the other hand if no catch is found the exception becomes a second chance exception within the debugging environment and this causes the debugger to break (if it’s configured to break on exceptions).

We can watch for first chance exceptions by adding an event handler to the AppDomain.CurrentDomain.FirstChanceException, for example

AppDomain.CurrentDomain.FirstChanceException += CurrentDomain_FirstChanceException;

private void CurrentDomain_FirstChanceException(
    object sender, FirstChanceExceptionEventArgs e)
{
   // maybe we'll log e.Exception
}

So first chance exceptions don’t tend to mean there’s problems within your code however using async/await, especially with void async methods you may find first chance exceptions are the a precursor for an unhandled exception from one of these methods.

If you check out Jon Skeet’s answer on stackoverflow to Async/await exception and Visual Studio 2013 debug output behavior he succinctly describes the problems that can occur with exception handling in async/await code.

To use this great quote “When an exception occurs in an async method, it doesn’t just propagate up the stack like it does in synchronous code. Heck, the logical stack is likely not to be there any more.”. With the async/await on a Task, the task itself contains any exceptions, but when there is no task, when we’re async/await on a void method, then there’s no means to propagate any exceptions. Instead these exceptions are more likely to first appear as First Chance exceptions and then unhandled exceptions.

See also https://msdn.microsoft.com/en-us/magazine/jj991977.aspx

Handling “unhandled” exceptions in WPF

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

None of us want our applications to just crash when an exception occurs so we often ensure we’ve got catch blocks around possible exceptions, but ofcourse, sometimes we either don’t care to handle an exception explicitly or we forget to code the catch block or the place the exception occurs such that it’s not possible to handle in such a structured way. In such scenarios we want to handle all “unhandled” exceptions at the application level.

Let’s take a look at some of the ways to handle exceptions in a WPF application. Here’s a list some of those ways to handle “unhandled” exceptions.

AppDomain.UnhandledException

The AppDomain.UnhandledException or more specifically AppDomain.CurrentDomain.UnhandledException.

Application.DispatcherUnhandledException

The Application.DispatcherUnhandledException or more specifically the Application.Current.DispatcherUnhandledException

Dispatcher.UnhandledException

The Dispatcher.UnhandledException or more specifically Dispatcher.CurrentDispatcher.UnhandledException

AppDomain.FirstChanceException

The AppDomain.FirstChanceException or more specifically AppDomain.CurrentDomain.FirstChanceException.

TaskScheduler.UnobservedTaskException

The TaskScheduler.UnobservedTaskException

C# 8.0 nullable and non-nullable reference types

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

One of the key C# 8.0 features is nullable/non-nullable reference types, but before we get started you’ll need to enable the language features by editing the csproj and adding the following to each PropertyGroup

<PropertyGroup>
    <LangVersion>8.0</LangVersion>
    <Nullable>enable</Nullable>
</PropertyGroup>

You can also enable/disable on a per file basis using

#nullable enable

and to disable

#nullable disable

What’s it all about?

So we’ve always been able to assign a null to a reference type (which is also the default value when not initialized), but ofcourse this means if we try to call a method on a null reference we’ll get the good old NullReferenceException. So for example the following (without #nullable enable) will compile quite happily without warnings (although you will see warnings in the Debug output)

string s = null;
var l = s.Length;

Now if we add #nullable enable we’ll get the warnings about that we’re attempting to assign a null to a non-nullable. Just like using the ? as a nullable for primitives, for example int? we now mark our reference types with the ?, hence the code now looks like this

string? s = null;
var l = s.Length;

In other words we’re saying we expect that the string might be a null. The use of the non-nullable on reference types will hopefully highlight possible issues that may result in NullReferenceExceptions, but as they’re currently warnings you’ll probably want to enable Warnings as Errors.

This is an opt-in feature for obvious reasons i.e. it can have a major impact upon existing projects.

Obviously you still need to handle possible null values. Partly because you might be working with libraries which do not have this nullable reference type option enabled, but also because we can “trick” the compiler – so we know the previously listed code will result in a Dereference of a possibly null reference warning, but what if we change things to the following

public static string GetValue(string s)
{
   return s;
}

// original code changed to
string s = GetValue(null);
var l = s.Length;

This still gives us a warning Cannot convert null literal to non-nullable reference type so that’s good but we can change GetValue to this

public static string GetValue([AllowNull] string s)
{
   return s;
}

and now, no warnings exist – the point being that even with nullable reference types enabled and not marking a reference type as nullable, we can still get null reference exceptions.

Attributes

As you’ve seen, there’s also (available in .NET core 3.0) some attributes that we can apply to our code to the compiler a little more information about our null expectations. You’ll need to use the following

using System.Diagnostics.CodeAnalysis;

See Update libraries to use nullable reference types and communicate nullable rules to callers for a full list of attributes etc.

Alignment using string interpolation in C#

C#’s string interpolation supports alignment and format options

Alignment

Using the following syntax, {expression, alignment}, we can use negative alignment numbers for left-aligned expressions and positive numbers for right-aligned alignment. For example

var number = 123;
Console.WriteLine($"|{number,-10}|");
Console.WriteLine($"|{number,10}|");

This would produce the following

|123       |
|       123|

See also Alignment component.

Format String

We can use the following {expression, alignment:format} or {expression:format} syntax to add formatting, i.e.

var number = 123;
Console.WriteLine($"|{number, -10:F3}|");
Console.WriteLine($"|{number, 10:F3}|");

would produce the following

|123.000   |
|   123.000|

and

var number = 123;
Console.WriteLine($"|{number:F3}|");
Console.WriteLine($"|{number:F3}|");

would produce

|123.000|
|123.000|

See also Format string component.

WPF Validation methods

How do we handle validation in WPF ?

Before we begin…

Let’s start by looking at the view model we’re going to work on and write our validation code for – this is a very simple model with a single property “Number” which could ofcourse represent anything you like.

public class NumberViewModel : INotifyPropertyChanged
{
   // standard implementation of INotifyPropertyChanged removed 
   private int number;

   public int Number
   {
      get { return number; }
      set
      {
         if (number != value)
         {
            number = value;
            OnPropertyChanged("Number");
         }
      }
   }
}

You can assume that OnPropertyChanged fires the INotifyPropertyChanged.PropertyChanged event, but I’ve removed the implementation for brevity.

We’ll be equally simple with our UI, which has the following XAML

<TextBox Text="{Binding Number}" />

Good old IDataErrorInfo

So if you’ve used IDataErrorInfo in WinForms, this will be very familiar to you. We can simple implement the IDataErrorInfo interface in our NumberViewModel and add something like the following

string IDataErrorInfo.Error
{
   get { return null; }
}

string IDataErrorInfo.this[string columnName]
{
   get
   {
      if (columnName == "Number")
      {
         if (number < 0)
            return "Number must be greater or equal to 0";
      }
      return null;
   }
}

To get the WPF binding to actually interact with the IDataErrorInfo we need to change the XAML to look like this

<TextBox Text="{Binding Number, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" />

In the above our IDataErrorInfo.this indexer will be called each time the property changes, at which time we can handle the validation either within the view model or ofcourse via some other validation rule class.

ValidationRule validation

An alternative to the IDataErrorInfo route for validation are ValidationRules. A ValidateRule implementation of the previous validator is listed below

public class PostiveValidationRule : ValidationRule
{
   public override ValidationResult Validate(object value, CultureInfo cultureInfo)
   {
      int result;
      if (value != null && Int32.TryParse(value.ToString(), out result))
      {
         if (result < 0)
            return new ValidationResult(
               false, "Number must be greater or equal to 0");
      }
      return ValidationResult.ValidResult;
   }
}

To use the above rule in XAML we write the following

<TextBox>
   <TextBox.Text>
      <Binding Path="Number" 
            ValidatesOnDataErrors="True" 
            UpdateSourceTrigger="PropertyChanged">
         <Binding.ValidationRules>
            <validators:PostiveValidationRule />
         </Binding.ValidationRules>
      </Binding>
   </TextBox.Text>
</TextBox>

The ValidationRules (as the pluralism suggests) can have multiple rules listed.

INotifyDataErrorInfo

.NET 4.5 included the INotifyDataErrorInfo. This allows us to validate in a more asynchronous way in that we can raise the ErrorsChanged event when we have errors and report them so that the binding engine can then call the GetErrors method to get the list of errors.

BindingGroup

The previously highlighted validation methods tend to be aimed more at a specific view model, but what if our view is made up of multiple view models and we want to validate across them all. Then we can look to use the BindingGroup.

The BindingGroup creates a relationship between multiple bindings, which can be validated and updated together.

To put it another way, the BindingGroup allows us to validate a group of bindings at the same time. Our sample only has a view model but if we had multiple view models it could validate all the items that make up a BindingGroup. Let’s look at how we could create a BindingGroup.

<StackPanel>
   <StackPanel.BindingGroup>
     <BindingGroup Name="ValidDataGroup">
        <BindingGroup.ValidationRules>
           <validators:ValidDataValidationRule />
        </BindingGroup.ValidationRules>
     </BindingGroup>
   </StackPanel.BindingGroup>
   <TextBox Text="{Binding Text, ValidatesOnDataErrors=True, BindingGroupName=ValidDataGroup}" />

We give the BindingGroup a name and then we can assign this name to the various bindings – in this example we don’t actually need to use the group name on the textbox as it will be used within the validation, but hopefully you can see how the syntax would look.

Now let’s take a look at the ValidDataValidationRule code

public class ValidDataValidationRule : ValidationRule
{
   public override ValidationResult Validate(object value, CultureInfo cultureInfo)
   {
      var bindingGroup = (BindingGroup)value;
      if (bindingGroup != null)
      {
         var numberViewModel = bindingGroup.Items[0] as NumberViewModel;
         if (numberViewModel != null)
         {
            if (numberViewModel.Number < 0)
            {
               return new ValidationResult(
                  false, 
                  "Number must be greater or equal to 0");
            }
         } 
      }
      return ValidationResult.ValidResult;
   }		
}

The Items collection will contain the various groups that have been assigned the BindingGroup name and then we can validate across all the data contexts.

Unfortunately, this doesn’t just happen magically. Instead, we need to invoke it. If we give the name DataElement to the StackPanel and for the sake of simplicity we add a button with a Click handler, we can then call the BindingGroup’s CommitEdit method to force validation, i.e.

DataElement.BindingGroup.CommitEdit();

Note: The default style is to draw a read line around the control which fails validation, if you’ve placed the StackPanel as the top level Window you might need to add a margin to see the red border.

ValidationStep

On both the BindingGroup and ValidationRule we can set the ValidationStep property. This allows us to tell the binding mechanism at what stage it should invoke the validation rule.

This can be set to one of four values

CommittedValue: Runs the ValidationRule after the value has been committed to the source.
ConvertedProposedValue: Runs the Validation rule after a value is converetd.
RawProposedValue: Runs the validation before any conversion occurs.
UpdatedValue: Runs the ValidationRule after the source is updated.

Note: The above definitions were taken from ValidationStep Enumeration

Data annotations

Finally, let’s take a look at data annotations or more specifically validation attributes that are part of the System.ComplonentMode.DataAnnotations namespace.

With the data annotations we can apply attributes to a class or its members which denote the validation rules to be used. For example

public class ValidationModel
{
   [Required(ErrorMessage = "First name is a required field")]
   public string FirstName { get; set; }
}

In this example we’ve removed the get/set actual implementation, for brevity.

Now this code requires use to write code to validation the property, for example in our setter we might have code like this

var validationContext = new ValidationContext(this, null, null);
validationContext.MemberName = nameof(FirstName);
Validator.ValidateProperty(value, validationContext);

Enhancing the user interface

So far, I’ve not done anything to make the user experience any better regarding validation, i.e. you will only see a red border around our text box, but this doesn’t really help the user identify what’s gone wrong, so now let’s look at how we might change our UI to better reflect the validation failures.

Ofcourse, we’ve been busy creating error messages, but so far not shown them in the UI, so we could use something like the following

<TextBox Text="{Binding Number, 
      UpdateSourceTrigger=PropertyChanged, 
      ValidatesOnDataErrors=True}">
   <Validation.ErrorTemplate>
      <ControlTemplate>
         <StackPanel>
            <AdornedElementPlaceholder />
            <TextBlock Text="{Binding [0].ErrorContent}" Foreground="Red"/>
         </StackPanel>
      </ControlTemplate>
   </Validation.ErrorTemplate>
</TextBox>

This will display the first error message just beneath the TextBox.

Another alternative is to style the text box with a trigger against the Validation.HasError property

<Style TargetType="{x:Type TextBox}">
   <Style.Triggers>
      <Trigger Property="Validation.HasError" Value="True">
         <Setter Property="Background" Value="Red" />
          <Setter Property="ToolTip"
             Value="{Binding RelativeSource={x:Static RelativeSource.Self},
             Path=(Validation.Errors)[0].ErrorContent}"/>
      </Trigger>
   </Style.Triggers>
</Style>

References

Data validation in WPF
Using BindingGroups For Greater Control Over Input Validation
BindingGroups For Total View Validation
WPF 3.5 SP1 Feature: BindingGroups with Item-level Validation
Validation in Windows Presentation Foundation

Assembly Redirects of Strong-Named Assemblies

It’s unfortunately all too often recently that I’ve need to redirect assemblies, so I thought I’d write a quick post on the subject.

Occasionally you may have a situation where one library (let’s call it Lib1) you’re using in .NET relies on a specific version of a another, strong-named, library (let’s call it Lib2). Then you go and update the library Lib2 to a newer version and things break. Lib1 expects a specific version of Lib2 and we’re not supplying it.

Simple open/add your App.config file – we then add something like this

<runtime>
  <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <dependentAssembly>
      <assemblyIdentity name="Lib2" publicKeyToken="Lib2-PublicToken" culture="neutral" />
      <bindingRedirect oldVersion="0.0.0.0-1.0.0.0" newVersion="2.0.0.0" />
    </dependentAssembly>
  </assemblyBinding>
</runtime>

Obviously you replace Lib2 with the assembly that your code is dependent upon, you’ll also need to supply the publicKeyToken. The oldVersion is a range of versions from 0.0.0.0 to 1.0.0.0 in this case, meaning anything that required this assembly version 0 to 1 should now use version 2 (2.0.0.0).

When adding further assembly redirects we of just supply further dependentAssembly elements.

To find the publicKeyToken we can use the Strong Name utility (sn.exe) which can be found here (for example)

"%ProgramFiles%\\Microsoft SDKs\Windows\v8.0A\bin\NETFX 4.0 Tools\sn.exe" -T <assemblyName>

We can also find such information via the likes of ILSpy, by clicking on the assembly and in the right hand pane we’ll have information such as

// Microsoft.VisualC, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a

Further Reading

Strong-Named Assemblies
Redirecting Assembly Versions

Computational Expressions, the “standard” methods

Note: This post was written a while back but sat in draft. I’ve published this now, but I’m not sure it’s relevant to the latest versions etc. so please bear this in mind.

So in a previous post I looked at my first attempt at creating a computational expression in F#. By anyone’s level this was basic. So I figured it was time to look at all the available “standard” methods available for a computational expression. By “standard” I means those which are implciitly recognized by F# as opposed to creating custom methods.

See Computation Expressions (F#) for more info.

There are plenty of posts on this subject from Microsoft or F# for fun or profit, so why am I writing yet another post – basically just to give my perspective and to help me remember this stuff.

Let’s start with the basics, we have a type SampleBuilder defined as

type SampleBuilder() =
   // our code will be filled is as required 
   // but an example might have just the following
   member this.Bind(m, f) = f m

We shall use the builder thus

let builder = SampleBuilder()

builder {
   // expressions, such as 
   let x = 100
}

and now to the various builder methods…

Bind

let! x = 100

// translates to

builder.Bind(100, (fun x -> expression))

So as can be seen, in essence the order of the arguments is reversed. So if we were to simply duplicate the way let binding works but in a computational expression we’d write something like

member this.Bind(m, f) = 
   f m

Return and ReturnFrom

At the time of writing this, I’m a little confused as to the difference between Return and ReturnFrom. Computation expressions and wrapper types states that the Return returns a wrapped type whilst ReturnFrom returns an unwrapped type. However it is seems it’s possible to pretty much return whatever I like as shown below

member this.Return(x) = x

member this.ReturnFrom(x) = x

Return is called when we have a return in the computation expression, i.e.

builder {
   return 100
} |> printfn "%A"

and ReturnFrom is used when return! exists, i.e.

builder {
   return! 100
} |> printfn "%A"

One slightly odd thing if you’re used to C# or the likes is that we can have multiple return and/or return! in a computational expression as per

builder {
   return 100
   return! 100
} |> printfn "%A"

As per multiple yield statements, we need a Combine method implemented in our builder to combine the return values. A return does not mean the rest of the computational expression is not executed, it means that the return values are combined to produce a value at the end of the workflow. So for example

builder {
   printfn "First"
   return 100
   printfn "Second"
   return 100
} |> printfn "%A"

Assuming our Return method and Combine are as simple as the following

member this.Return(x) = 
   printfn "Return"
   x

member this.Combine(a, b) = a + b

Then our output will look like the following

First
Return
Second
Return
200

In other words, the first printfn (actually the Delay builder method is called for each printfn) is called then the Return method, then the second printfn then the second Return, then the Combine is called. In this case Combine simply adds the return values together to produce the output of the workflow.

Combine

The combine method combines multiple values – so for example if you had something like the following

builder {
   yield 100
   yield 200
} |> printfn "%A"

without a combine method you’ll get the following compiler error This control construct may only be used if the computation expression builder defines a ‘Combine’ method. Simple enough to see the problem here. So we cannot yield more than once unless we implement a combine method. Here’s an example which implements the combine by creating a list and combining elements into a new list

member this.Combine(a, b) = a @ b

If we now compile this code we’ll get another error, “This control construct may only be used if the computation expression builder defines a ‘Delay’ method”. So we need to implement a Delay method. See the example listed for Delay below…

Delay

The Delay method allows the builder to delay the evaluation of a computational expression until it’s required. For example if we yield multiple times within a computational expression the idea is to combine the yields until we’re ready to invoke something.

The example above creates a list of the yields and then in the Delay we might want to do something with those combined yields. In this example below we’ll simply use the following code

member this.Delay(f) = f()

which essentially just invokes the function passed to the delay.

Run

Whilst the Delay method is used to delay evaluation, the Run method is mean’t to use the delayed expression, i.e. it might be to run something or the likes. An example which simply turns the list created by the combine into an array instead

member this.Run(f) = Array.ofList f

this is obviously a rather simplistic example, had our builder been creating the data for a web service call, for example, possibly run would make the call for us.

For

I again must point anybody reading this section to the excellent post Implementing a builder: The rest of the standard methods where an implementation of the For method is describe, for simplicity I’ll recreate it here

member this.For(sequence:seq<_>, body) =
   this.Using(sequence.GetEnumerator(),fun enum -> 
      this.While(enum.MoveNext, 
         this.Delay(fun () -> body enum.Current)))

The Using, While and Delay methods are described elsewhere in this post.

Here’s some sample code using the For method from our computational expression block

builder {        
   for i = 1 to 10 do
      printfn "%d" i
} 

TryFinally

An implementation of the TryFinally method is fairly straightforward

member this.TryFinally(body, compensation) =
   try this.ReturnFrom(body())
   finally compensation() 

and in usage within a computational expression block, we have

builder {        
   try
      let x = 1 / 0
      printfn "should not make it to here"
   finally
      printfn "exception"
} 

In the above code, when we step into the try block we will actually enter the TryFinally method and obviously this then takes over executing the body of the code and then executing the finally block.

TryWith

Very much like the TryFinally block, we have the following implementation

member this.TryWith(body, handler) =
   try this.ReturnFrom(body())
   with e -> handler e

and an example of the computational expression block might be

builder {        
   try
      let x = 1 / 0
      printfn "should not make it to here"
   with
   | :? DivideByZeroException -> printfn "divide by zero"
} 

Using

As the name suggests, this is used for IDisposable types. Here’s a sample of it’s implementation

member thisTryFinally(body, compensation) =
   try __.ReturnFrom(body())
   finally compensation() 

member this.Using(disposable:#System.IDisposable, body) =
   let body' = fun () -> body disposable
   this.TryFinally(body', fun () -> 
      match disposable with 
      | null -> () 
      | disp -> disp.Dispose())

The Using method relates to the use! keyword and hence we might have code such as

builder {        
   use! x = new MemoryStream()
   printfn "do something with the memory stream"
} 

So at the point use! is invoked our Using method takes over. We i

While

The example of a while loop in a computational expression was lifted from “Implementing a builder: The rest of the standard methods” and I highly recommend anyone visiting this post goes and reads the computational expression series on F# for fun and profit.

So our example code is as follows

let mutable i = 0
let test() = i < 5
let inc() = i <- i + 1

let builder = SampleBuilder()

builder {        
   while test() do
      printfn "%i" i
      inc()         
} |> ignore

It’s important to note that the three let statements at the top of the source must be global or you’ll get an error along the lines of “The mutable variable ‘i’ is used in an invalid way. Mutable variables cannot be captured by closures. Consider eliminating this use of mutation or using a heap-allocated mutable reference cell via ‘ref’ and ‘!’.”

So our builder code should look something like the following

member this.Bind(m, f) = f m

member this.Return(x) = x

member this.Zero() = this.Return ()

member this.Delay(f) = f

member this.Run(f) = f()

member this.While(guard, body) =
   if not (guard()) 
   then 
      this.Zero() 
   else
      this.Bind( body(), fun () -> 
         this.While(guard, body))  

So as can be seen, in the While method we are passed the guard and the body of the while loop and as expected we need to invoke these bits of code to evaluate them. When the guard completes we invoke the Zero method which in this case simply called the Return method. If the loop has not completed we simply keep looping.

Yield and YieldFrom

We can use yield or yield! from a computational expression, but to do so we need to implement the Yield and YieldFrom methods (respectively) on the builder, otherwise we’ll be greeted with the “This control construct may only be used if the computation expression builder defines a ‘Yield’ method”, here’s an example of the yield being used from a computational expression block

builder {
   yield 100
} |> printfn "%A"

// or

builder {
   yield! 100
} |> printfn "%A"

An example of the Yield and YieldFrom methods in the builder might look like the following

member this.Yield(x) = Some x

member this.YieldFrom(x) = x

Zero

You may have noticed, if you’ve written your own builder type that something like the following

builder {
}

// or

builder {
} |> ignore

doesn’t compile, this is because a computational expression must have something within the curly braces. So if instead we write the following

builder {
   printfn "Hello"
}

We’re get an altogether different error at compile time stating This control construct may only be used if the computational expression builder defines a ‘Zero’ method. Basically a computational expression must return something, either explicitly or implicitly. In this case Zero is used for any implicit return, so we could resolve this error using

member this.Zero() = ()

or ofcourse we might implicitly return the same thing we would with an explicit return such as

member this.Return(x) = x

member this.Zero() = this.Return ()