Author Archive

5e vlinderdag – Marieke de Koning

www.mariekedekoning.nl

Code Snippet: change background color of Visual Studio editor with code

When working on a project which has a trunk and branches, it happens sometimes that I am changing code at the wrong location. To make it clear that I am working on a branch I added some VB Macro to the Visual Studio IDE which changes the background color when the solution is stored in a directory called “branches”.

Sub ChangeBackgroundColorForBranchProjects() Handles SolutionEvents.opened, DocumentEvents.documentopening
        Dim backgroundColor As UInt32
        backgroundColor = &HFFFFFF
        If (DTE.Solution.FullName.ToLower.Contains("branches")) Then
            backgroundColor = &HC0FFFF
        End If

        CType(DTE.Properties("FontsAndColors", "TextEditor").Item("FontsAndColorsItems").Object, EnvDTE.FontsAndColorsItems).Item("Plain Text").Background = backgroundColor
    End Sub

You can easily add above code to Visual Studio by using the Macro IDE. I put this code within the (by default exisiting) EnvironmentEvents file part of the MyMacros project.

This simple code snippet checks only if the solution fullname (which includes the path) contains the word “branches”. It is of course possible to write more intelligent behaviour which looks for example to a setting file within your solution. Just use this as a starting point. Hopefully it will reduce the number of times that you are changing code within the wrong solution.

Getting things done and Outlook – Keep original message attached to task or appointment

To get my email, tasks and mind organized, I am trying to use the Getting Things Done method developed by David Allen (English book/Dutch book). Because I am using Outlook as “external storage system”, I read an additonal book (Iedere dag je hoofd en inbox leeg (dutch book)) about implementing GTD within Outlook.

The main idea of this book is that you copy emails to task lists or your agenda during the processing phase with the use of some shortcuts. With the default Copy to folder functionality of Outlook, this works quite okey with two exceptions:

  • Attachments are not copied to a task/agenda item
  • You don’t have a reference to the original message, so you are not able to reply if you finished a task or need additional information

I developed a macro with some VBA code which will create a new Outlook item (appointment or task) and attaches the orginal message to this new item. This way I can always open the original email (with attachments) and sent a reply without looking up the email in the archive folder first.

Sub CopyEmailToNewItem()

    Dim objMailItem As Outlook.mailItem

    If (ActiveExplorer.Selection.Count = 1) And (ActiveExplorer.Selection.Item(1).Class = olMail) Then
        Set objMailItem = ActiveExplorer.Selection.Item(1)
    End If

    Dim NameSpace As Outlook.NameSpace
    Set NameSpace = Outlook.GetNamespace("MAPI")

    Dim selectedFolder As Folder
    Set selectedFolder = NameSpace.PickFolder

    Const attPath As String = "C:\temp\"

    Set objNewItem = selectedFolder.Items.Add(selectedFolder.DefaultItemType)
    With objNewItem
        .Subject = objMailItem.Subject
        .Body = objMailItem.Body

        objMailItem.SaveAs attPath & objMailItem.EntryID

        .Attachments.Add attPath & objMailItem.EntryID, olEmbeddeditem, , "Orginal message"

        Kill (attPath & objMailItem.EntryID)

        .Display
    End With
End Sub

Unittesting with WCF client dependency

On the Internet I found a simple calculator webservice (http://soatest.parasoft.com/calculator.wsdl). In this blogpost I will build a really simple class library which exposes the Add operation of this webservice. The purpose of this exercise is to show you how to handle this WCF dependency when unit testing the code.

Calculator 1.0 – Using the generated client

Based on the WSDL you normally create a proxy. I prefer the use of svcutil (this makes it possible to repeat the proxy generation based on command line arguments)

svcutil /serializer:DataContractSerializer /n*:ServiceProxy /out:CalculatorProxy.cs calculator.wsdl

This generated proxy will be used in the first version of the Calculator class library

using System;
using System.ServiceModel;
using ServiceProxy;

namespace CalculatorOne
{
    /// <summary>
    /// Implementation of a calculator which provides simple arithmetic operations
    /// </summary>
    public class Calculator
    {
        /// <summary>
        /// Adds two numbers and returns the result
        /// </summary>
        /// <param name="numberOne"></param>
        /// <param name="numberTwo"></param>
        /// <returns></returns>
        public float Add(float numberOne, float numberTwo)
        {
            float response = 0f;
            var calculatorClient = new CalculatorClient();

            try
            {
                response = calculatorClient.add(numberOne, numberTwo);
                calculatorClient.Close();
            }
            catch (CommunicationException)
            {
                calculatorClient.Abort();
            }
            catch (TimeoutException)
            {
                calculatorClient.Abort();
            }
            catch (Exception)
            {
                calculatorClient.Abort();
                throw;
            }

            return response;
        }
    }
}

There is quite some code for calling just a simple Add operations. Most of the code is related to exception handling to make sure that the connection is closed correctly. Don’t use the using statement to let the client proxy automatically dispose the connection, because an exception can occur within the dispose logic: http://msdn.microsoft.com/en-us/library/aa355056.aspx

Besides the huge amount of code, you are not possible to test this code without connecting to a real service. Which means that unit testing is not possible. Only integration tests against the real service are possible but you don’t want to depend on the availability of this service. When unit testing the Add operation of your library you are not interested in testing the real service. You are only interested if the dependency to the external service is called.

Time for version 2.0 of the Calculator class library which will inject the WCF client proxy to make mocking possible

Calculator 2.0 – Inject the WCF client dependency with the use of the ChannelFactory

I prefer the use of Moq (http://code.google.com/p/moq/) as a simple mocking library. Moq only supports mocking of interfaces and virtual methods of classes. The generated proxy by svcutil does not contain virtual methods so you are unable to mock this class. Besides the generated client, there is also a channel interface (ICalculatorChannel) generated. With the WCF ChannelFactory you are able to instantiate a proxy client based on this interface.

using System;
using System.ServiceModel;
using ServiceProxy;

namespace CalculatorTwo
{
    /// <summary>
    /// Implementation of a calculator which provides simple arithmetic operations
    /// </summary>
    public class Calculator
    {
        private readonly ICalculatorChannel calculatorClient;

        public Calculator(ICalculatorChannel calculatorClient)
        {
            this.calculatorClient = calculatorClient;
        }

        /// <summary>
        /// Adds two numbers and returns the result
        /// </summary>
        /// <param name="numberOne"></param>
        /// <param name="numberTwo"></param>
        /// <returns></returns>
        public float Add(float numberOne, float numberTwo)
        {
            float response = 0f;

            try
            {
                response = calculatorClient.add(numberOne, numberTwo);
                calculatorClient.Close();
            }
            catch (CommunicationException)
            {
                calculatorClient.Abort();
            }
            catch (TimeoutException)
            {
                calculatorClient.Abort();
            }
            catch (Exception)
            {
                calculatorClient.Abort();
                throw;
            }

            return response;
        }
    }
}

Now it is possible to inject a mocked client proxy when unit testing. This way you can tests if the dependency is called in the right way and you don’t depend on the availability of a real service

[TestMethod]
public void Add_WhenClientIsMocked_ShouldMockBeCalled()
{
    //Arrange
    var client = new Mock<ICalculatorChannel>();
    client.Setup(c => c.add(It.IsAny<float>(), It.IsAny<float>())).Returns(42);

    var calculator = new Calculator(client.Object);

    //Act
    float response = calculator.Add(30, 12);

    //Assert
    client.Verify(c => c.add(30, 12), Times.Once());
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

For assertions, I prefer the use of the FluentAssertions library (http://fluentassertions.codeplex.com/). This makes the test more readable. Above tests shows that it is possible to unit test the Add method of the Calculator class library. Still there is a lot of exception handling code and also the consumer of this class is now responsible for creating the client proxy

[TestMethod]
public void Add_When30And12IsProvidedAsInput_Should42BeReturned()
{
    //Arrange
    var factory = new ChannelFactory<ICalculatorChannel>("ICalculator");
    var calculator = new Calculator(factory.CreateChannel());

    //Act
    float response = calculator.Add(30, 12);

    //Assert
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

First let’s get rid of the close connection and exception handling code. Let’s move on to Calculator 3.0

Calculator 3.0 – Introducing a reusable client proxy

The code for closing the client proxy connection together with the exception handling code will be used for each service operation call. By introducing a client proxy this code can be removed from the method implementation

using System;
using System.ServiceModel;

namespace CalculatorThree
{
    public class ClientProxy<TChannel> : IClientProxy<TChannel> where TChannel : ICommunicationObject
    {
        private readonly TChannel innerChannel;

        public ClientProxy(TChannel innerChannel)
        {
            this.innerChannel = innerChannel;
        }

        public TResult Execute<TResult>(Func<TChannel, TResult> operation)
        {
            TResult result = default(TResult);

            try
            {
                result = operation(innerChannel);
                innerChannel.Close();
            }
            catch (CommunicationException)
            {
                innerChannel.Abort();
            }
            catch (TimeoutException)
            {
                innerChannel.Abort();
            }
            catch (Exception)
            {
                innerChannel.Abort();
                throw;
            }

            return result;
        }
    }
}

The Execute method makes use of a Func. Within the Add method implementation you are able to define which service operation of the proxy you want to use (together with the needed arguments). The Calculator Add method will be change to this

using ServiceProxy;

namespace CalculatorThree
{
    /// <summary>
    /// Implementation of a calculator which provides simple arithmetic operations
    /// </summary>
    public class Calculator
    {
        private readonly IClientProxy<ICalculatorChannel> clientProxy;

        public Calculator(IClientProxy<ICalculatorChannel> clientProxy)
        {
            this.clientProxy = clientProxy;
        }

        /// <summary>
        /// Adds two numbers and returns the result
        /// </summary>
        /// <param name="numberOne"></param>
        /// <param name="numberTwo"></param>
        /// <returns></returns>
        public float Add(float numberOne, float numberTwo)
        {
            return clientProxy.Execute(c => c.add(numberOne, numberTwo));
        }
    }
}

The code is a lot cleaner (there is no connection closing and exception handling clutter anymore). Because the new client proxy can still be injected (IClientProxy) it is even still testable. For the unit test you are only interested if the dependency is called

[TestMethod]
public void Add_WhenClientProxyIsMocked_ShouldClientProxyBeCalled()
{
    //Arrange
    var clientProxy = new Mock<IClientProxy<ICalculatorChannel>>();
    clientProxy.Setup(p => p.Execute(It.IsAny<Func<ICalculatorChannel, float>>())).Returns(42);
    var calculator = new Calculator(clientProxy.Object);

    //Act
    float response = calculator.Add(30, 12);

    //Assert

    //it is not possible / quite difficult to check with which arguments the func was called. This has to do that Moq cannot evaluate the expression.
    //therefore only the call is checked. If we want to now if the correct arguments where set, we just mock the internal proxy of the client proxy
    clientProxy.Verify(c => c.Execute(It.IsAny<Func<ICalculatorChannel, float>>()), Times.Once());
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

When using the ClientProxy implementation it is still possible to mock the internal proxy. This way you are also able to check if the service operation is called with the correct arguments. This is not a unit test, but a unit integration tests: the calculator together with the client proxy are tested together

[TestMethod]
public void Add_WhenInnerProxyOfClientProxyIsMocked_ShouldInnerProxyBeCalledWithCorrectArguments()
{
    //Arrange
    var innerProxy = new Mock<ICalculatorChannel>();
    innerProxy.Setup(i => i.add(It.IsAny<float>(), It.IsAny<float>())).Returns(42);

    var clientProxy = new ClientProxy<ICalculatorChannel>(innerProxy.Object);

    var calculator = new Calculator(clientProxy);

    //Act
    float response = calculator.Add(30, 12);

    //Assert
    innerProxy.Verify(c => c.add(30, 12), Times.Once());
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

Still the consumer should create the internal proxy with the use of the ChannelFactory as shown in below integration test. To simplify this, a ProxyFactory will be introduced in Calculator version 4.0

[TestMethod]
public void Add_When30And12IsProvidedAsInput_Should42BeReturned()
{
    //Arrange
    var factory = new ChannelFactory<ICalculatorChannel>("ICalculator");
    var clientProxy = new ClientProxy<ICalculatorChannel>(factory.CreateChannel());

    var calculator = new Calculator(clientProxy);

    //Act
    float response = calculator.Add(30, 12);

    //Assert
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

Calculator 4.0 – Introducing a proxy factory

By introducing a proxy factory, the logic for creating a proxy with the use of the ChannelFactory can be moved to a common and reusable place.

using System.ServiceModel;

namespace CalculatorFour
{
    public class WCFProxyFactory : IProxyFactory
    {
        #region IProxyFactory Members

        public IClientProxy<TChannel> GetProxy<TChannel>(string endpointName) where TChannel : ICommunicationObject
        {
            var factory = new ChannelFactory<TChannel>(endpointName);
            return new ClientProxy<TChannel>(factory.CreateChannel());
        }

        #endregion
    }
}

The use of this proxy factory will change the calculator implementation a little bit

using ServiceProxy;

namespace CalculatorFour
{
    /// <summary>
    /// Implementation of a calculator which provides simple arithmetic operations
    /// </summary>
    public class Calculator
    {
        private readonly IProxyFactory proxyFactory;

        public Calculator(IProxyFactory proxyFactory)
        {
            this.proxyFactory = proxyFactory;
        }

        /// <summary>
        /// Adds two numbers and returns the result
        /// </summary>
        /// <param name="numberOne"></param>
        /// <param name="numberTwo"></param>
        /// <returns></returns>
        public float Add(float numberOne, float numberTwo)
        {
            return proxyFactory.GetProxy<ICalculatorChannel>("ICalculator").Execute(c => c.add(numberOne, numberTwo));
        }
    }
}

Still unit, unit integration and integration testing is possible! The integration test also shows that using the Calculator class library is now more straightforward

//Unit test
[TestMethod]
public void Add_WhenClientProxyIsMocked_ShouldClientProxyBeCalled()
{
    //Arrange
    var clientProxy = new Mock<IClientProxy<ICalculatorChannel>>();
    clientProxy.Setup(p => p.Execute(It.IsAny<Func<ICalculatorChannel, float>>())).Returns(42);

    var proxyFactory = new Mock<IProxyFactory>();
    proxyFactory.Setup(p => p.GetProxy<ICalculatorChannel>(It.IsAny<string>())).Returns(clientProxy.Object);

    var calculator = new Calculator(proxyFactory.Object);

    //Act
    float response = calculator.Add(30, 12);

    //Assert

    //it is not possible / quite difficult to check with which arguments the func was called. This has to do that Moq cannot evaluate the expression.
    //therefore only the call is checked. If we want to now if the correct arguments where set, we just mock the internal proxy of the client proxy
    proxyFactory.Verify(p => p.GetProxy<ICalculatorChannel>("ICalculator"), Times.Once());
    clientProxy.Verify(c => c.Execute(It.IsAny<Func<ICalculatorChannel, float>>()), Times.Once());
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

//Unit integration test
[TestMethod]
public void Add_WhenInnerProxyOfClientProxyIsMocked_ShouldInnerProxyBeCalledWithCorrectArguments()
{
    //Arrange
    var innerProxy = new Mock<ICalculatorChannel>();
    innerProxy.Setup(i => i.add(It.IsAny<float>(), It.IsAny<float>())).Returns(42);

    var clientProxy = new ClientProxy<ICalculatorChannel>(innerProxy.Object);

    var proxyFactory = new Mock<IProxyFactory>();
    proxyFactory.Setup(p => p.GetProxy<ICalculatorChannel>(It.IsAny<string>())).Returns(clientProxy);

    var calculator = new Calculator(proxyFactory.Object);

    //Act
    float response = calculator.Add(30, 12);

    //Assert
    innerProxy.Verify(c => c.add(30, 12), Times.Once());
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

//Integration test
[TestMethod]
public void Add_When30And12IsProvidedAsInput_Should42BeReturned()
{
    //Arrange
    var factory = new WCFProxyFactory();

    var calculator = new Calculator(factory);

    //Act
    float response = calculator.Add(30, 12);

    //Assert
    response.Should().BeGreaterOrEqualTo(42).And.BeLessOrEqualTo(42);
}

What’s next?

This blog post shows that it is possible to unit tests a class/method which has a dependency with a WCF Client. By introducting the additional classes, the implementation becomes clean and testable.

In the final version of the calculator the proxy factory is injected by using constructor injection. It is off course possible to resolve this dependency with an IoC (http://en.wikipedia.org/wiki/Inversion_of_control) implementation like StructureMap (http://structuremap.net/structuremap/) whereby the factory can be resolved without the use of constructor or property injection.

You can find the samples shown in the blogpost at codeplex: http://johandekoning.codeplex.com/SourceControl/changeset/view/67443#1165211

Dam tot damloop 2010

19 september om 11:30 was het dan zo ver… de start van mijn eerste dam tot damloop. Het hardloopevenement waarvoor ik in maart met trainingen bij AV Zaanland was begonnen. Toen begon ik met 1 minuut hardlopen en was dan al kapot. Nu een half jaar verder heb ik er 16,1 km opzitten in 1 uur 39 minuten en 33 seconden.

Het meedoen aan de dam tot damloop is erg gaaf. Ik zelf vond het door te ijtunnel lopen toch wel een hoogtepunt van het parcours omdat ik daar enkel met de bus of auto doorheen ben gereden. Maar ook de hoeveelheid mensen langs de weg maakt een enorme indruk. Ik ga de training bij AV Zaanland doorzetten dus wellicht volgend jaar weer…

Uitslag
Video’s

WCF Data Contract Schema validation with Schematron

WCF is mostly used within a code first implementation. The data contract and service operations are implemented as methods within a class which are decorated with attributes (like [DataContract] and [DataMember]). With these attribute the types define that they are serializable with a serializer such as the DataContractSerializer. The DataContractSerializer is an optimized serializer which is faster than the XmlSerializer (http://www.danrigsby.com/blog/index.php/2008/03/07/xmlserializer-vs-datacontractserializer-serialization-in-wcf/). A consequent of this optimalization is that only a subset of the XML Schema (XSD) is supported: http://msdn.microsoft.com/en-us/library/ms733112.aspx

When working with existing systems, it is most times not possible to use the code first approach for the definition of the data contract. XSD and WSDL are exposed by existing services which makes client proxy and data contract code generation possible with the use of svcutil. By default svcutil tries to use to DataContractSerializer and falls back to the XmlSerializer when usage of the DataContractSerializer is not possible (it is possible to force the use of the data contract serializer by supplying the /serializer:datacontractserializer argument, which not falls back to the XmlSerializer but returns an error when it is not able to generate the code).

Within a situation that WSDL and XSD are leading but changes can be made to support the DataContractSerializer, it can be time consuming to update those service definitions files. The svcutil tool gives limited feedback when it fails to use the DataContractSerializer and it does not give you a clear overview of the issues that should be solved to make it compliant to this serializer.

Schematron

Schematron is a rule-based validation language for making assertions about the presence or absence of patterns in XML trees. It is a structural schema language expressed in XML using a small number of elements and XPath. (http://en.wikipedia.org/wiki/Schematron). With the use of a Schematron rule set file, additional conditions can be defined for the data contract schema definition.

Schematron (http://www.schematron.com/) is an ISO standard (http://standards.iso.org/ittf/PubliclyAvailableStandards/c040833_ISO_IEC_19757-3_2006(E).zip) and makes it possible to define constraints which cannot be expressed/defined within a XML Schema (XSD). It is possible to define rules which take related elements into account. Within a Schematron rule set file, rules are made by specifying assertions. An example of a rule

<sch:pattern id="schema-element-attribute-error">
	<sch:rule context="xsd:schema/xsd:element">
		<sch:assert test="@nillable = 'true'">Must be true for associated GEDs.</sch:assert>
	</sch:rule>
</sch:pattern>

Above rules makes sure that global element declarations (xsd:element directly defined within xsd:schema) should have the nillable=”true” attribute.

Besides <assert> there is also a <report> assertion. When the Schematron rule set is applied on an XML file, <assert> is logged when the condition fails (positive assertions). On the other side <report> is logged (within the output file) when the condition is met (negative assertions). For example when above rule fails on the supplied data contract schema definition, the output file (SVRL, Schematron Validator Report Language) will contain:

<svrl:active-pattern id="schema-element-attribute-error" name="schema-element-attribute-error"/>
	<svrl:fired-rule context="xsd:schema/xsd:element"/>
	<svrl:failed-assert test="@nillable = 'true'" location="/*[local-name()='schema' and namespace-uri()='http://www.w3.org/2001/XMLSchema']/*[local-name()='element' and namespace-uri()='http://www.w3.org/2001/XMLSchema'][1]">
		<svrl:text>Must be true for associated GEDs.</svrl:text>
	</svrl:failed-assert>
<svrl:fired-rule context="xsd:schema/xsd:element"/>

whereby the location of the element causing this failure is part of the result message (location attribute).

Applying an schematron ruleset

A Schematron rule set file is converted to an XSLT file which will be applied on the XML file on which the assertions should be executed. This is a pipelined process whereby the Schematron file is tranformed by different XSL files (and an XSLT engine) as shown in the diagram below

When using the basic elements of Schematron, only one transformation is needed before it can be applied on a file which should be validated. I used the Schematron XSLT1 implementation (http://www.schematron.com/tmp/iso-schematron-xslt1.zip) together with the free AltovaXML XSLT Engine (http://www.altova.com/altovaxml.html)

AltovaXML /xslt1 iso_svrl_for_xslt1.xsl /in datacontract.sch /out datacontract.xsl
AltovaXML /xslt1 datacontract.xsl /in <xsd schema which should be checked>  /out result.svrl

Data Contract Validator

With the use of Schematron it is possible to make a data contract serializer validator, which gives you a quick overview of issues to make use of the Data Contract Serializer possible. I developed a first implementation of this rule set based on the Data Contract Schema Reference (http://msdn.microsoft.com/en-us/library/ms733112.aspx). Not all rules are implemented yet.

When validating a data contract XSD there are errors (a Global Element Declarations should have @nillable=’true’) and warnings (attribute @id is ignored). To distinguish between both validation types I used for the errors, and for warnings/verbose information.

You can download the Data Contract Schematron Rule set at http://johandekoning.codeplex.com/SourceControl/changeset/view/48265#831939

Turing machine implementation with WF4 and FlowChart

A couple of days ago I received a tweet about a real hardware implementation of the Turing Machine (http://www.aturingmachine.com/). Impressed about this implementation, I was thinking about how to implement a simple Turing Machine counting program with the use of Workflow Foundation 4. And that’s where the story starts about my first experience with WF4.

Turing machine definition

At Wikipedia a definition of the Turing machine can be found: http://en.wikipedia.org/wiki/Turing_machine. To keep it short, a Turing machine consists of two parts

  • A tape of unlimited length which is separated in cells
  • A machine that can read/write on the tape

The machine is a finite state machine. The machine is in one state and with the use of a set of rules the machine can transfer to a different state. A rule contains the following parts

  • current state
  • symbol read
  • next state
  • symbol to write
  • move direction

The following rule [state: 0, read: blank, new state: 1, write: blank, move: left] will be executed by the machine when the current state is 0 and the value of the cell on the tape is blank. When the rule is executed, the machine will transfer to state 1, keeps the cell blank and will move the tape one cell to the left. A next rule for state 1 will be executed based on the new cell value read on the new tape position.

The machine part will be written with the use of a workflow diagram. This diagram will contain the different states and rule actions.

Counting rules

The rules for making counting possible (as taken from the aturingmachine.com website)

[state: 0, read: 1, new state: 0 write: 1, move: right]
[state: 0, read: 0, new state: 0, write: 0, move: right]
[state: 0, read: blank, new state: 1, write: blank, move: left]

[state: 1, read: 0, new state: 0, write: 0, move: right]
[state: 1, read: 1, new state: 1, write: 0, move: left]
[state: 1, read: blank, new state: 0, write: 1, move: right]

Tape implementation

The tape is a collection of cells which has an unlimited length. New cells can be added at the start or end of the written tape part. To support this functionality, an implementation is made based on a List collection making it possible to not only add new values at the end of the tape but also at the beginning.

public class Tape : ITape
    {
        public int Position { get; private set; }
        public int Length { get { return _internalCollection.Count; } }

        private List<int?> _internalCollection;

        public Tape()
        {
            Position = 0;
            _internalCollection = new List<int?>(){null};
        }

        public int? ReadCell()
        {
            return _internalCollection[Position];
        }

        public void WriteCell(int? cellValue)
        {
            _internalCollection[Position] = cellValue;
        }

        public void MoveCell(MoveDirection direction)
        {
            switch(direction){
                case MoveDirection.Left:
                    if (Position == 0)
                    {
                        _internalCollection.Insert(0, null);
                    }
                    else
                    {
                        Position--;
                    }
                    break;
                case MoveDirection.Right:
                    Position++;
                    if (Position == _internalCollection.Count)
                    {
                        _internalCollection.Add(null);
                    }
                    break;
            }
        }

        public override string ToString()
        {
            StringBuilder tapeValue = new StringBuilder("[");
            foreach (var cell in _internalCollection)
            {
                if (cell == null) { tapeValue.Append(" "); } else { tapeValue.Append(cell.ToString()); }
            }
            tapeValue.Append("] ");
            return tapeValue.ToString();
        }
    }

Flowchart

The state workflow of Workflow Foundation 3 is not part of version 4. The alternative given is the flowchart. With the flow chart certain types of state machine workflows can be implemented (but not all of them). A flowchart is powerful and simple to use, making it possible to loop back to previous executed activities. This is very useful for moving between the different states.

Together with the Flowchart, two activities are introducted: FlowDecision and FlowSwitch. A FlowDecision can be seen as an if condition while the FlowSwitch is like a switch statement in code. The FlowSwitch will be the central decision node for each state within the turing machine counting implementation

Workflow implementation with standard activities

A console workflow application is used for this implementation. An instance of the Tape is set as variable on the FlowChart.

The counting program can be developed with the use of the standard activities provided by WF4. The following activities are used

  • FlowSwitch: based on the cell value an execution path is chosen
  • InvokeMethod: used for executing the WriteCell and MoveCell methods
  • WriteLine: write the value of all cell values to the console.
  • Delay: this activiity is optional. Some delay to make output more readable during execution

The default path of the FlowSwitch activity is used for supporting the blank values. This is because of the fact that FlowSwitch works with string values, making it impossible to define a path for a null value.

Custom activities

The InvokeMethod activity is a generic activity to make execution of a method possible. It takes some time to configure each activity. The method parameters (for example the cell value which should be written) are implemented as a Parameter collection, which are not directly visible from the property editor within Visual Studio. To simplify/fasten this assignment process, custom activities will be developed to support the specific methods on the Tape instance.

Custom code activities are based on the CodeActivity or NativeActivity class. The CodeActivity is for creating simple synchronous custom activities. This model is suitable for the custom activities needed by the turing machine workflow. When you want to use all of the functionality exposed by the WF4 runtime, you should use the NativeActivity base class.

Two custom activities are developed

  • MoveCell activity: for moving the position on the tape one cell. The Direction property holds the move direction
  • WriteCell activity: for writing a cell value on the current position. The CellValue property holds the value which should be written
namespace TuringMachine.Activities
{
    [Designer(typeof(MoveCellDesigner))]
    public sealed class MoveCell : CodeActivity
    {
        [RequiredArgument()]
        public InArgument<ITape> Tape { get; set; }

        public MoveDirection Direction { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            var tape = context.GetValue(Tape);
            tape.MoveCell(Direction);
        }
    }
}
namespace TuringMachine.Activities
{
    [Designer(typeof(WriteCellDesigner))]
    public sealed class WriteCell : CodeActivity
    {
        [RequiredArgument()]
        public InArgument<Nullable<int>> CellValue { get; set; }

        [RequiredArgument()]
        public InArgument<ITape> Tape { get; set; }

        protected override void Execute(CodeActivityContext context)
        {
            var tape = context.GetValue(Tape);
            var cellValue = context.GetValue(CellValue);

            tape.WriteCell(cellValue);
        }
    }
}

The InArgument type used for the properties can hold (besides a value like a normal property) an expression. Those expression are defined using the VB.Net language (so null should be defined as Nothing)

The custom activities are added to the Workflow Toolbox making it possible to drag them into the workflow. You can change the property values from within the Property editor

Custom design

When viewing the diagram, it is still not directly clear which values are written and to which direction the position on the tape is moved. WF4 makes it possible to assign a design to a custom activity. The design of the activity is developed with XAML. Assignment is done with the use of the Designer attribute (as shown in the code above)

The XAML used for the MoveCell activity makes it possible to directly select the move direction from within the diagram

<sap:ActivityDesigner x:Class="TuringMachine.Activities.Designer.MoveCellDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
    xmlns:sys="clr-namespace:System;assembly=mscorlib"
    xmlns:tm="clr-namespace:TuringMachine.Classes;assembly=TuringMachine.Classes">
    <sap:ActivityDesigner.Resources>
        <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="MoveDirectionValues">
            <ObjectDataProvider.MethodParameters>
                <x:TypeExtension TypeName="tm:MoveDirection"/>
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </sap:ActivityDesigner.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock VerticalAlignment="Center">Direction:</TextBlock>
        <ComboBox Grid.Column="1" ItemsSource="{Binding Source={StaticResource MoveDirectionValues}}" SelectedValue="{Binding ModelItem.Direction, Mode=TwoWay}"></ComboBox>
    </Grid>
</sap:ActivityDesigner>

And the WriteCell Activity makes the cell value assignment possible from within the workflow diagram. For the WriteCell activity an ExpressionTextBox is used, supporting the InArgument expression possibilities.

<sap:ActivityDesigner x:Class="TuringMachine.Activities.Designer.WriteCellDesigner"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
    xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
    xmlns:conv="clr-namespace:System.Activities.Presentation.Converters;assembly=System.Activities.Presentation"
    xmlns:local="clr-namespace:TuringMachine.Activities.Designer"
    xmlns:sys="clr-namespace:System;assembly=mscorlib">
  <sap:ActivityDesigner.Resources>
    <conv:ArgumentToExpressionConverter x:Key="expressionConverter"/>
  </sap:ActivityDesigner.Resources>
  <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock VerticalAlignment="Center">Cell value</TextBlock>
        <sapv:ExpressionTextBox Grid.Column="1" Expression="{Binding Path=ModelItem.CellValue, Mode=TwoWay, ConverterParameter=In, Converter={StaticResource expressionConverter}}" ExpressionType="{local:NullableExtension sys:Int32}" OwnerActivity="{Binding Path=ModelItem}"></sapv:ExpressionTextBox>
    </Grid>
</sap:ActivityDesigner>

Workflow implementation with custom activities

With the use of the developed custom activities together with their design, the diagram of the workflow will give us directly more information related to the execution of the program

What’s next?

My first impression about WF4 is that the usage is more simplified. Within the previous version of WF you had to write a lot of code to execute external methods. With the use of the CodeActivity (or NativeActivity) class it is easy to implement custom activities. The possibility to use XAML to layout your custom activities is very powerful. It makes it possible to implement diagrams which are visual more meaningful (especially useful when hosting the WF designer within your own application). While the FlowChart is not a real State Workflow, it is suitable for the implementation written above. The usage feels more natural, just like developing a sequence workflow.

While developing the counting workflow I had some issues with the support of Nullable types and the ExpressionTextBox. I needed to implement an TypeExtension to make it possible to define the ExpressionType as a Nullable. This was not what I expected because XAML 2009 (XAML version of .Net 4) should make it possible to define the type as {x:Type TypeName=System:Nullable`1[[System.Int32]]}. But this syntax is not accepted as valid.

Source code

The visual studio 2010 solution including the workflows and source code files can be found at (http://johandekoning.codeplex.com -> browse to WF/TuringMachine)

Powershell – Sync/shift file creation time

I went on holiday for two weeks together with my girlfriend. We both had our own camera and when we returned home we wanted to merge both photo collections. There was only a small problem, the date/time settings of the cameras were not in sync. This will give you funny/strange results when viewing the slideshow.

To solve this issue, I created a small powershell script. As an argument you provide a datetime string (format ddMMyyyyHHmmss). The oldest file (inside the directory where you execute this script) will get this new provided creation date. The creation date of the other files is updated taken the same time span (between oldest file date and the provided date) into account. Executing this script on one of the photo collections will make it possible to merge both collections.

$oldestFile = dir | sort-object CreationTime | select -first 1

$newStartDateTime = [datetime]::ParseExact($args,"ddMMyyyyHHmmss",$null)
$timespan = $newStartDateTime - $oldestFile.CreationTime

dir | foreach { $_.CreationTime = ($_.CreationTime + $timespan)}

My colleague went to a conference and all I got was this lousy eco-button

Today I got an eco button from my colleague. It is a hardware button with a green flashing light (is that eco?) which can be connected to your computer. With software installed, your computer will be put in stand-by mode when you press the button.

Because I use my computer the whole day for development, I don’t need an eco-button. I need an build project button for the Visual Studio development environment. A little hack is really easy to make and the result will be a more impressive build routine :)

Pressing the button (after connecting it to your computer without installing the ecobutton software) will execute the keys command

Windows-Key+R ecobutton ENTER

In my opinion a stupid implementation, because each time you press the button you see a Run dialog, followed by the “ecobutton” text filled in and finished with an enter. But this way it is quite easy to replace ecobutton.exe with your own application (keeping the same name)

So I developed a little console application (maybe a hidden application is even better) which will search my Visual Studio application and send the key command F6 (you can also send CTRL+SHIFT+B).

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Diagnostics;

namespace WhatDoesThisButtonDo
{
    class Program
    {
        [DllImport("user32.dll")]
        static extern bool SetForegroundWindow(IntPtr hWnd);

        static void Main(string[] args)
        {
            IntPtr hWnd = IntPtr.Zero;

            foreach (var p in Process.GetProcesses())
            {
                if (p.ProcessName.Equals("devenv")) {
                    hWnd = p.MainWindowHandle;
                    break;
                }
            }

            if (hWnd != IntPtr.Zero)
            {
                SetForegroundWindow(hWnd);
                SendKeys.SendWait("{F6}");
            }
        }
    }
}

Explaining the code

When pressing the ecobutton, Visual Studio is not the active application anymore. Therefore I first have to find the window handler (of Visual Studio), make it the active foreground application and send the F6 key. There is a FindWindow method (user32.dll) but this one is based on the caption on the title bar. Because your solution name is part of this caption, the name is not static. To solve this issue I loop through the different processes to find the devenv process (when multiple visual studio’s are running, only one is used in this sample).

The SetForegroundWindow brings Visual Studio to the foreground. The F6 key is sent with SendKeys.SendWait. Instead of the F6 key you can also send the CTRL+SHIFT+B keystrokes by supplying “^+B”

To use this small applicaton, make sure it is called ecobutton.exe and placed within your PATH (otherwise Windows is unable to find it).

For me the Build button is way better than the Eco button version, but probaly you have better/other implementation suggestions what you can do with this hardware device. Please post them as feedback on this blogpost.

Top2OneNote Addin – Making my digital notepad notes searchable

Last week I bought a nice gadget at our discount supermarket (Aldi). The gadget is called a Digital notepad and makes it possible to record your notes while writing them down on paper. Your writing is stored on the internal memory as vector data. There is a lot of software supplied, but using them is not that straightforward.

Digital notepad

Most of the software supplied with this gadget wants to convert the note to clear text. But because of my bad handwriting, most of the time the converted text makes no sense. I also want to keep the drawing which I added to my notes. So instead of converting it to text, I would be happy if I can archive the notes and make them searchable.

Microsoft OneNote gives Tablet PC users the option to add handwritten notes to there OneNote notebook. Those notes are made searchable, while the handwritten note still exists. Instead of using a Tablet PC I want to convert my Digital Notepad content to OneNote handwritten notes. And therefore I developed a small OneNote addin which makes this possible. The source code together with the installer can be found at http://top2onenote.codeplex.com. Within this blogpost, I will explain some of the steps I took to make this addin possible.

Reading a TOP file

There is less information available about the file format that is generated by the Digital Notepad. The file extension is called .Top and it looks like it is a format invented by Waltop International Corp. When searching on the Internet for more information I found this blogpost together with some perl and python scripts to convert a Top file to SVG. I will use the logic of these scripts to convert my notes to OneNote.

Develop an OneNote AddIn

Visual Studio 2008 gives you the possiblity to develop Office Add Ins. There are different project templates supplied for Word, Excel and Outlook… but not for OneNote. There are no Visual Studio templates available for OneNote, so developing a AddIn is not that easy. Again Google gives me a nice search result, a blogpost about creating a toolbar addin for OneNote 2007: http://blogs.msdn.com/descapa/archive/2006/08/31/734298.aspx. There is a step by step tutorial supplied which will explain the different steps to develop a toolbar Addin which will popup a Hello world message. The AddIn will make use of COM Interop, which makes it possible to use C#.

The interface which should be implemented does only contains two methods. I found out that using this interface will only gives you the active OneNote page. With the OneNote.ApplicationClass (part of the Microsoft.Office.OneNote.Interop assembly) you will update the OneNote page outside OneNote. This means that the functionality of your addin does not run within OneNote, but inside a DllHost container.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.InteropServices;
using OneNote = Microsoft.Office.Interop.OneNote;

namespace Top2OneNoteAddIn
{
   [ComImport, Guid("C9590FA7-2132-47fb-9A78-AF0BF19AF4E6")]
   public interface IOneNoteAddIn
   {
      bool OnClick([In] String strActivePageID);

      bool OnEvent([In] OneNote.OneNoteAddIn_Event evt, [In] String strParameter);
   }
}

Note: together with OneNote 2007 I also installed the OneNote 2010 Beta. It seems like the AddIn functionality will change, because the addin is shown on the toolbar but clicking on it does not trigger the functionality. I think that with the release of OneNote 2010 that I will be easier to develop OneNote Addins, probably with the use of a Visual Studio template.

OpenFileDialog issue

The AddIn should, when clicked, open up a file dialog where the user can select the .top file which should be imported. Because the plugin does not run for within OneNote, the OpenFileDialog was shown below the OneNote window. I found a solution by supplying the Windows handler of OneNote as owner of the OpenFileDialog. This way the dialog is shown on top of OneNote

Process[] procs = Process.GetProcessesByName("OneNote");
IntPtr hwnd = procs[0].MainWindowHandle;

OpenFileDialog dialog = new OpenFileDialog();
dialog.Filter = "top files (*.top)|*.top|All files (*.*)|*.*";
dialog.Title = "Select a top file";
dialog.ShowDialog(new WindowWrapper(hwnd));

A little WindowWrapper class is added to the solution, which implements the IWin32Window interface making it possible to supply the window handler as argument to the ShowDialog method.

public class WindowWrapper : System.Windows.Forms.IWin32Window
{
        private IntPtr _hwnd;

        public WindowWrapper(IntPtr handle)
        {
            _hwnd = handle;
        }

        #region IWin32Window Members

        public IntPtr Handle
        {
            get { return _hwnd; }
        }

        #endregion
}

InkAnalyzer

The vector data from the top file is converted to a collection of Stroke objects (for which the constructor gets a StylusPointCollection as argument). Those stoke objects are set to the InkAnalyzer. The Analyze method performs layout analysis, writing and drawing classification, and handwriting recognition. The result is given back as an AnalysisStatus object which will be used for building the XML structure used to update the OneNote page.

InkAnalyzer analyzer = new InkAnalyzer();
analyzer.AddStroke(stroke);

AnalysisStatus status = analyzer.Analyze();
if (status.Successful)
{
   Console.WriteLine(analyzer.GetRecognizedString());
}

The AddStroke method has overloaded method for which you can specify the languageId of the stroke. By default the locale settings of the active thread will be used. In my case the Dutch language id was used (because of my region settings). I use English as my OS display language. When the Dutch language pack is not installed, the result of the analyzer will not be successful. So keep in mind to check if the correct language packs are installed to make handwritten recognition possible. The method analyzer.GetInkRecognizersByPriority() gives back a list of available InkRecognizers for the different languages.

Building the OneNote XML

You can update OneNote pages by providing a XML structure. Adding or updating depends if objectids are supplied. If this is the case, the object will be updated. An example of the XML used to add the handwritten notes to OneNote

<?xml version="1.0"?>
<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/2007/onenote"
        ID="{C6CCDE4D-7F47-46FA-9DD6-0A4CEC503E86}{1}{B0}">
	<one:Outline>
		<one:Position x="209.9905395507812" y="126.0"/>
		<one:Size width="245.2818908691406" height="125.3196716308594"/>
		<one:OEChildren>
			<one:OE>
				<one:InkWord recognizedText="hallo">
					<one:Data>AMIGHQSQBOYCAYABKgAaH4tCcEWEdYC+0EXZBFjPVIrml8VPjwb4utLhmyK/
7HHMzCKxQYkOuxMs7nqh3rsTi+Ves0icm6ElWrdREvqHlTLy7BdBuMAWv/Mr9HrEZm2nDbJYSZodTkA0BmwQRVOAL
HoY1USZZUo0BjFbMxSVQJ6SzJhLtWqQHBLFWlUDC0gURSNGI1cNAAAABQcLZU9mZ2hpGRQyCACAHgIh4uJBMwgA
4BICSvPiQRGrqtNBZAMVRgBAShs20YdmzeA0YdmxgA6YdmsBow7GLAB0w7Nm8AAATxMEawMVRgBAahA+gEXPAA
ARXQADggAAIqIAAAqKAW+C/gdb+B19kqxUublEssCwCSiblSgFlABLLFSyypYWLLFlliiC/gR7+BH7ACTZc3LJqblks2W
CzZQ2VNliyklZSMkzVmrKsVKSgNyygAoAESBQIxrXX3TKARMEEgARIKFVgU7sSj5OjNx+XqrpdDQFFEYAQAAABRRGA
QAAAAoAESDcOupAmua8QApiMYL+CJP4IlAAAEoAAEoAgv4BG/gEfKycSbsm5di0qry2bEGy8tUKABEg4IA52V90ygE
TBBIAESCouC8UZctFT6fx0sc+lOXuBRRGAEAAAAUURgFAAAAKP0Aj06oIUjE4DWAKWiGC/gnj+CeQBBZZQACC/gEj
+ARWM5yUt25ddnaFiwAKABEgIH932l90ygETBBIAESAf+viILJADTKojJ+vOFaLHBRRGAEAAAAUURgGAAAAJFiKA30M
Qcv/ZAAp0SYL+BFP4EVAACUALAkJRU3NypSbCwUCC/gDT+ANeJMktzPHc7Le7dtVaNy7WOIgkuJbmpZGrZQAKAB
EgYAtv1V90ygETBBIAESAUVWvkl8H9TbQgjxGuoKlABRRGAEAAAAUURgDAAAAKP0Ai63IF0ksIC+AKggFlgv4MK/gw
25SpYsFlhLAESwlsmybLNypbKAssqWUlllixZYsAgv4EY/gRkAlgZYWWFlEs2WaFUTZVkqJUuUlgAssssVAACgARIGBI
qdtfdMoBEwQSABEgk453gdolgkGItwM1/odLkQUURgBAAAAFFEYBwAAACgARIGLKJkG7kLtA
					</one:Data>
				</one:InkWord>
			</one:OE>
		</one:OEChildren>
	</one:Outline>
	<one:Outline>
		<one:Position x="225.0141754150391" y="461.2535400390625"/>
		<one:Size width="680.25830078125" height="80.7023696899414"/>
		<one:OEChildren>
			<one:OE>
				<one:InkWord recognizedText="dit">...
					</one:Data>
				</one:InkWord>
				<one:InkWord recognizedText="is">
					<one:Data>...
					</one:Data>
				</one:InkWord>
				<one:InkWord recognizedText="een">
					<one:Data>...</one:Data>
				</one:InkWord>
				<one:InkWord recognizedText="test">
					<one:Data>...
					</one:Data>
				</one:InkWord>
			</one:OE>
		</one:OEChildren>
	</one:Outline>
</one:Page>

Only the data for the first word is shown in this example to keep things clear. At the root element (Page) the ID of the existing page (provided as argument of the OnClick method) to define that the content should be inserted to the page.The InkWord data are stored as Ink Serialized Format with BASE64 encoding and placed together with the recognizedText to make searching within the handwritten notes possible.

InkWordNode iwNode = node as InkWordNode;

using (MemoryStream ms = new MemoryStream())
{
   iwNode.Strokes.Save(ms);
   byte[] isfBytes = ms.ToArray();
   dataNode.SetValue(Convert.ToBase64String(isfBytes));
}

Updating OneNote

Updating the OneNote page is done by creating an instance of the OneNote.ApplicationClass. The UpdatePageContent method is used whereby the created XML structure is supplied as argument. There is a little delay between executing the importer and when the page is updated. The cause of this delay is probally that the OneNote page is updated outside OneNote and that it will be triggered to refresh the page content.

OneNote.ApplicationClass onApplication = new OneNote.ApplicationClass();

XNamespace one = "http://schemas.microsoft.com/office/onenote/2007/onenote";
XElement root = new XElement(one + "Page", new XAttribute(XNamespace.Xmlns + "one", one));
root.Add(new XAttribute("ID", strActivePageID));

BuildXML(analyzer.RootNode, root, one);

onApplication.UpdatePageContent(root.ToString(), DateTime.MinValue);

What’s next?

The result of the importer is the same when writing the text directly with the use of a Tablet PC. Probably the results of a Tablet PC are maybe even more secure, but that’s also the reason that I don’t want to convert the handwritten notes to text.

Search within a handwritten note

Search within a handwritten note

The importer could be optimized in different ways. Some issues/ideas to improve this add in

  • Language selection – selected by import or set as a preference
  • Insert at cursor position – currently the location is set to the top left. It is possible to retrieve the cursor position by requesting the page content (GetPageContent) with the use of the OneNote.ApplicationClass. The location of the cursor is marked as a selection inside the retrieved XML structure
  • Improve text recognition – the InkAnalyzer has different properties to improve the text recognition. This way better results are achieved
  • Drag and drop support – instead of using the open file dialog, it would be nice if you can just drag the top file on your OneNote page

Like I mentioned, you can find the source at http://top2onenote.codeplex.com. It is not my goal to put a lot of effort in the development of this AddIn. If you are interested in improving this AddIn, send some feedback and I can add you as contributor to this project. If you have other questions, ask them and I will try to answer them.