Showing posts with label C#. Show all posts
Showing posts with label C#. Show all posts

Friday, April 5, 2013

BASTA! Spring Slides on agile Architecture Patterns


It’s been some weeks now that I gave a talk at the german BASTA! Spring Conference. I talked again about software architecture in agile environments. The focus this time was more about patterns and their realization with C#/.NET.
You may download the slides (which are in german) as well as the presented example implementations. Please notice that the examples were only build for the talk to show several architectural concepts, so they are not properly commented or tested nor do they follow any clean code guidelines.
       

Thursday, August 9, 2012

C# Operator Overloading for Improved Code Readability

In this blog post I’m going to show you some basic stuff concerning operator overloading in C#. Operators can be very useful in situations where you want to write elegant and easy to understand code by using standard C# syntax. For this post I will use a simple API that creates Crystal Reports selection formulas out of a given DataSet and some operators.

Introduction: Crystal Syntax
In order to understand why operators perfectly fit this usage scenario we need to have a short glimpse at the Crystal syntax for selection formulas. Selection formulas enable you to filter the displayed data inside a Crystal Reports report according to the underlying data. Often you use a dataset and bind it to a report which in turn gets shown in the Crystal Reports Viewer. Formulas are given as pure strings, so if you want to use the programmatically you have to learn Crystal Syntax which is not really fun. Let’s have a look at the basic concepts:

  • Column References
References to Columns of the underlying data source are written as {TableName.ColumnName}. So if you have a dataset with a table called Customer and a Column called name, you would write {Customer.Name}.

  • Comparison Operators
You can use comparison operators in order to compare a column value to any given value. Beneath the standard comparison operators like ‘less than’ or ‘greater than’ or ‘equals’ you also have some string operators like ‘starts with’ or ‘like’. So you could write something like the following: {Customer.Name} startswith ‘A’.

  • Boolean Operators
Simple Expressions like the one shown above can be concatenated by using Boolean operators. Crystal Reports supports Not, And, Or, Xor, Eqv and Imp. Here’s an example: {Customer.Name} startsWith ‘A’ and {Customer.Age} < 18.

I think that’s enough for the moment to get started. If you want to see more operators or want to play around with selection formulas use the formula editor of the Crystal Reports designer in Visual Studio.

Crystal Syntax Converter
I don’t feel comfortable writing magic strings in code without getting them checked by some instance. Selection formulas can become very complex and error prone. So I searched for a solution to write down C# code and get the string generated out of it. My first approach was some kind of fluent API, so I could write something like the following:

Customer.NameColumn.StartsWith(“A”).And(Customer.AgeColumn.LessThan(18))

The result of this expression is equivalent to the Boolean Operators example above. But it’s much longer and more difficult to read. So I dropped that approach and turned to operator overloading. As stated at the beginning, operators are very powerful when used in appropriate situations. For our example we need to overload binary operators in order to get boolean operators and of course the comparison operators.

Let’s start with the very simplest expression. We want to use a column of our data source and compare it to any other value (e.g. a string or number). I start by writing a simple extension method, because I don’t want to write down DataSet.Table.Column every time and I need a custom object where I can define the overloaded operators. The custom class will be called CrystalColumn and the extension method looks like this:

public static CrystalColumn ToCrystalColumn(this DataColumn dc)
{
    var sb = new StringBuilder("{");
    sb.Append(dc.Table.TableName);
    sb.Append(".");
    sb.Append(dc.ColumnName);
    sb.Append("}");

    return new CrystalColumn(sb.ToString());
}

The method simply takes in a DataColumn and creates a string representation of it according to the Crystal Syntax. So now we a are able to write:

var firstname = dataSet.Customer
.FirstNameColumn.ToCrystalColumn();

The next step would be to overload the needed operators on the CrystalColumn class. Here’s the example of the ‘less than’ operator:

public static SingleExpression operator <(CrystalColumn column, int value)
{
    return new SingleExpression(column.ToString() + " < " + value);
}

The method needs to be static and the first parameter depicts the object on which the operator is defined. The provided objects are converted to the according string representation and passed to a new instance of the SingleExpression class. This class encapsulates a simple expression. With the code so far we can write the following:

var age = dataSet.Customer.AgeColumn.ToCrystalColumn();
var singleExpression = age < 18;

That feels much more natural and even looks better, doesn’t it? Here’s another example of the ‘starts with’ operator, which is of course no operator in the sense of C# operators but we need it for our expression:

public SingleExpression StartsWith(params string[] s)
{
    var startsWithExpression = "'" + s[0] + "'";

    if (s.Length > 1)
    {
        startsWithExpression = "[";
        for (int i = 0; i < s.Length; i++)
        {
            startsWithExpression += "'" + s[i] + "'";
            if (i < s.Length - 1)
                startsWithExpression += ",";
        }
        startsWithExpression += "]";
    }

    var expression = columnExpression + " startswith " + startsWithExpression;
    return new SingleExpression(expression);
}

The ’starts with’ operator in Crystal Reports acceppts an array of strings. That’s why the method acceppts a string array as parameter. Again a string represenation of the provided objects is created and passed to a new instance of the SingleExpression class. This method allows us to write:

var firstname = dataSet.Customer.FirstNameColumn.ToCrystalColumn();
var singleExpression = firstname.StartsWith("Mike", "John");

What’s missing now is the ability to combine two or more simple expressions by employing boolean operators to form complex expressions. In order to achieve this, we can now overload the needed binary operators on the SingleExpression class. For example the ‘And’ operator can be overloaded as follows:

public static Expression operator &(SingleExpression ex1, SingleExpression ex2)
{
    return ex1.And(ex2);
}

private Expression And(SingleExpression singleExpression)
{
    return new Expression(this,
singleExpression, LogicalOperator.and);
}

The operator overload takes a second SingleExpression instance and calls the private ‘And’ method. This method in turn creates a new Expression instance that encapsulates two or more simple expressions and finally generates the needed string representation. As another example I will show you the implementation of the ‘Not’ operator:

public static SingleExpression operator !(SingleExpression ex)
{
    return new SingleExpression(
"not (" + ex.ToString() + ")");
}

The method takes only one argument, because the ’Not’ operator is an unary operator acting on a single argument. According to this only a simple expression is returned.

Putting it all together
With the classes and method we have so far, we can now write our example expression using operators:

var firstname = dataSet.Customer.FirstNameColumn.ToCrystalColumn();
var age = dataSet.Customer.AgeColumn.ToCrystalColumn();

var expression = firstname.StartsWith("A", "B") & age < 18;

When you compare that statement to the first approach, I think it’s easy to see that the readability improved a lot. We can also compare it to the resulting formula in Crystal Syntax and see that it is as nearly as short as the formula:

{Customer.FirstName} startswith ['A','B'] and {Customer.Age} < 18

The Expression class overwrites its ToString method in order to write out the complete selection formula, so you can now easily pass it to the report viewer:

crystalViewer.SelectionFormula = expression.ToString();

Summary
This was only a short example of operator overloading in C# but I hope you noticed the great benefit of using them. If you need more information about C# operators just search the internet. It’s not a new concept. Some words of wisdom: Operators are not reasonable in every situation. Additionally when you use them be sure to use them the correct way and implement only operations that act the way a user would expect them to do. If you for example implement the ‘+’ operator for a custom number class, don’t return the difference. People are anticipating the results of common operations and get confused if something strange happens.

kick it on DotNetKicks.com

Monday, May 28, 2012

Resetting local Ports and Devices from .NET

Currently, I am working on C# applications that communicate with several external devices connected via USB ports. In rare cases the ports just stop working correctly, so we needed a programmatic approach to reset them. Doing this by using C# is not trivial. The solution we implemented uses the following components:
-          C#’s SerialPort class
-          WMI (Windows Management Instrumentation)
-          P/Invoke with calls to the Windows Setup API

Accessing a port using C#
Using a certain port with C# is rather simple. The .NET framework provides the SerialPort class as a wrapper to the underlying Win32 port API. You can simply create a new instance of the class by providing the name of an existing port. On the instance object you have methods to open or close the port or to read and write data from its underlying stream. It also provides events to notify any listeners when data or errors were received. Here is a small example on how to open a port by first checking if the given port name exists in the operating system:

public SerialPort OpenPort(string portName)
{
    if (!IsPortAvailable(portName))
    {
        return null;
    }

    var port = new SerialPort(portName);

    try
    {
        port.Open();
    }
    catch (UnauthorizedAccessException) { ... }
    catch (IOException) { ... }
    catch (ArgumentException) { ... }
}

private bool IsPortAvailable(string portName)
{
    // Retrieve the list of ports currently mounted by
    // the operating system (sorted by name)
    string[] ports = SerialPort.GetPortNames();
    if (ports != null && ports.Length > 0)
    {
        return ports.Where(new Func<string, bool>((s) =>
        {
            return s.Equals(portName,
                            StringComparison.InvariantCultureIgnoreCase);
        })).Count() == 1;
    }
    return false;
}

In rare cases the Open method of the port threw an IO Exception in our applications. This situation was not reproducible but also not acceptable. We noticed that after deactivating the port in the device manager and reactivating it, everything was working fine again. So we searched for a solution to do exactly the same thing from code.

Enable/Disable Devices
First of all a function or set of functions was needed to disable and enable a certain port. This can not directly be done from C# and needs some P/Invoke calls to the Win32 API. Luckily others had similar problems and so I found a very good solution at http://www.eggheadcafe.com/community/csharp/2/10315145/enabledisable-comm-port-by-programming.aspx. It uses the device installation functions from the Win32 Setup API. All you need is to retrieve the class GUID for the device set and the instance Id for the specific device you want to disable or enable. Just have a look at the link for the code or download the accompanying code for this blog post.

Retrieving the Ports Instance Id
Last thing to do is to acquire the correct instance Id for our port. We need a method that takes in the port name and retrieves the corresponding instance Id. For the exact definition of an instance Id in windows terms have a look at http://msdn.microsoft.com/en-us/library/windows/hardware/ff541224(v=vs.85).aspx. In our case we’d like to use the Plug ‘n’ Play device Id that can also be seen in the properties window of a device inside the device manager. For this purpose we are going to use WMI. If you need information about WMI have a look at http://msdn.microsoft.com/en-us/library/windows/desktop/aa394582(v=vs.85).aspx. WMI provides the Win32_SerialPort class that can be used to iterate over all mounted ports of the operating system. Two properties of the Win32_SerialPort class are important for us: The DeviceID property which represents the port name and the PNPDeviceID which gives the Plug ‘n’ Play instance Id. Notice while this works perfectly for Plug 'n' Play devices it may not work for other kinds of devices.

ManagementObjectSearcher searcher =
    new ManagementObjectSearcher("select * from Win32_SerialPort");
foreach (ManagementObject port in searcher.Get())
{
    if (port["DeviceID"].ToString().Equals(portName))
    {
        instanceId = port["PNPDeviceID"].ToString();
        break;
    }
}

If we found the appropriate instance Id we can use it together with the Win32 Setup API to retrieve a device info set and the corresponding device info data. If a device info for the instance Id was found we can use its class GUID and the instance Id to disable and enable the device. The following method is used to reset a port with a given instance Id:

public static bool TryResetPortByInstanceId(string instanceId)
{
    SafeDeviceInfoSetHandle diSetHandle = null;
    if (!String.IsNullOrEmpty(instanceId))
    {
        try
        {
            Guid[] guidArray = GetGuidFromName("Ports");

            //Get the handle to a device information set for all
            //devices matching classGuid that are present on the
            //system.
            diSetHandle = NativeMethods.SetupDiGetClassDevs(
                ref guidArray[0],
                null,
                IntPtr.Zero,
                SetupDiGetClassDevsFlags.DeviceInterface);

            //Get the device information data for each matching device.
            DeviceInfoData[] diData = GetDeviceInfoData(diSetHandle);

            //Try to find the object with the same instance Id.
            foreach (var infoData in diData)
            {
                var instanceIds =
                        GetInstanceIdsFromClassGuid(infoData.ClassGuid);
                foreach (var id in instanceIds)
                {
                    if (id.Equals(instanceId))
                    {
                        //disable port
                        SetDeviceEnabled(infoData.ClassGuid, id, false);
                        //wait some milliseconds
                        Thread.Sleep(200);
                        //enable port
                        SetDeviceEnabled(infoData.ClassGuid, id, true);
                        return true;
                    }
                }
            }
        }
        catch (Exception)
        {
            return false;
        }
        finally
        {
            if (diSetHandle != null)
            {
                if (diSetHandle.IsClosed == false)
                {
                    diSetHandle.Close();
                }
                diSetHandle.Dispose();
            }
        }
    }
    return false;
}

With the code set up so far we can now easily reset a port in case we’re getting an IO Exception while trying to open the port. We just have to call the method inside our exception handler and try to open the port again. That solved our initial problem. Be aware that it may take some time to disable and re-enable the port. It may be a good idea to do it inside a separate thread if you’re working inside an application using a GUI.


Download the sample code file: PortHelper.cs

Monday, November 21, 2011

WPF - Working with XML and XmlDataProvider

Working with XML or XML related data is not always easy in C#. With .NET Framework 3.0 Microsoft introduced the XmlDataProvider as part of the data provider infrastructure. Using XmlDataProvider inside WPF applications together with some XPath expressions makes it really easy to bind whatever kind of Xml fragment you have to some user interface controls. This blog entry shows how to use the provider by showing a simple example.

The XML Data
First of all, we need some sample data. I used the data from the XmlDataProvider example at the according
MSDN site:


<Inventory xmlns="">
  <Books>
    <Book ISBN="0-7356-0562-9" Stock="in" Number="9">
      <Title>XML in Action</Title>
      <Summary>XML Web Technology</Summary>
    </Book>
    <Book ISBN="0-7356-1370-2" Stock="in" Number="8">
      <Title>Programming Microsoft Windows With C#</Title>
      <Summary>C# Programming using the .NET Framework</Summary>
    </Book>
    <Book ISBN="0-7356-1288-9" Stock="out" Number="7">
      <Title>Inside C#</Title>
      <Summary>C# Language Programming</Summary>
    </Book>
    <Book ISBN="0-7356-1377-X" Stock="in" Number="5">
      <Title>Introducing Microsoft .NET</Title>
      <Summary>Overview of .NET Technology</Summary>
    </Book>
    <Book ISBN="0-7356-1448-2" Stock="out" Number="4">
      <Title>Microsoft C# Language Specifications</Title>
      <Summary>The C# language definition</Summary>
    </Book>
  </Books>
  <CDs>
    <CD Stock="in" Number="3">
      <Title>Classical Collection</Title>
      <Summary>Classical Music</Summary>
    </CD>
    <CD Stock="out" Number="9">
      <Title>Jazz Collection</Title>
      <Summary>Jazz Music</Summary>
    </CD>
  </CDs>
</Inventory>

We have an inventory containing books and CDs. Every book and CD has two child elements: title and summary. Books got an additional attribute for their ISBN number. The data is stored in a separate XML file.

The View
We will create a very simple WPF view for displaying our data. It will contain a combo box in order to select books or CDs. A list box will display the items of a category and the user will be able to select a single item and to display its properties. Furthermore the user may change the summary of the selected item. Here is a screenshot of the view:



Binding the Data
XmlDataProvider exposes several ways to access xml data
- inline xml with the
x:XData element
- set the Source property to an
URI
- set the Document property to a XmlDocument object

I will use the Source property and set it to the path of the xml file. I do this in code behind, inside the constructor:

var directory = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
if(!string.IsNullOrEmpty(directory))
{
    provider.Source = new Uri(Path.Combine(directory, "Inventory.xml"));
}

With the provider set up, we can now define the Binding inside the view:
<Window x:Class="XmlDataProviderSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="280" Width="600">
  <Window.Resources>
    <XmlDataProvider x:Key="dataProvider"/>
  </Window.Resources>
  <StackPanel>
    <ComboBox x:Name="inventoryTypeComboBox" ItemsSource="{Binding Source={StaticResource dataProvider}, XPath=/Inventory/*}">
      <ComboBox.ItemTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding Name}" />
        </DataTemplate>
      </ComboBox.ItemTemplate>
    </ComboBox>
    <StackPanel Margin="0,9,0,0" Orientation="Horizontal" DataContext="{Binding ElementName=inventoryTypeComboBox, Path=SelectedItem}">
      <ListBox x:Name="listBox" ItemsSource="{Binding Path=ChildNodes}">
        <ListBox.ItemTemplate>
          <DataTemplate>
            <TextBlock Text="{Binding XPath=Title}"/>
          </DataTemplate>
        </ListBox.ItemTemplate>
      </ListBox>
      <Grid Margin="6,0,0,0" DataContext="{Binding ElementName=listBox, Path=SelectedItem}">
        <Grid.ColumnDefinitions>
          <ColumnDefinition/>
          <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition/>
          <RowDefinition/>
          <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <TextBlock Text="ISBN: "></TextBlock>
        <TextBlock Grid.Column="1" Text="{Binding XPath=@ISBN}"></TextBlock>
        <TextBlock Grid.Row="1" Text="Summary: "></TextBlock>
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding XPath=Summary}"/>
      </Grid>
    </StackPanel>
    <Grid>
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="60"/>
        <ColumnDefinition Width="60"/>
      </Grid.ColumnDefinitions>
      <Button Margin="3,6,3,0" Content="Save" Grid.Column="1" Click="OnSaveClicked"/>
      <Button Margin="3,6,6,0" Content="Exit" Grid.Column="2" Click="OnExitClicked"/>
    </Grid>
  </StackPanel>
</Window>

Let’s start by examining the combo box. Its ItemsSource property is bound to the XmlDataProvider. The root node is selected by using an XPath expression. It selects all direct children of the inventory node, which are in that case books and CDs. In order to show some friendly text inside the combo box it defines an ItemTemplate, which has a TextBlock bound to the Name property of the current XmlNode. The XPath expression returns a list of XmlNode objects. Therefore you can bind to any property of that object. You could also bind to another XPath expression based on the current node.

A ListBox shall show all the items of the selected category. The data context of the container containing the list box is bound to the currently selected item of the combo box. That item is an XmlNode object, so the list box can be bound to the nodes ChildNodes collection. You don’t need to specify the Path attribute, but it makes the code more readable. Again we’re defining an ItemTemplate for the list. This time we use an XPath expression to bind to the title node in order to display the inventory item title inside the list. We could have also bound to the InnerText property of the XmlNode. Use whatever you like.

When the user selects an item in the list, its properties shall be shown next to the list and at least the summary shall be editable. The data context of the Grid container element is therefore bound to the selected item of the list box. Inside the Grid are TextBlocks for displaying the ISBN and the summary of the currently selected inventory item. The summary is displayed inside a TextBox so the user may change it. Note, that the ISBN is an attribute of the book node, so you have to use an @ symbol inside the XPath expression.

Changing and Saving Data
XmlDataProvider keeps an XmlDocument with an XmlNode object collection of the xml document in memory. Using the xml API in .NET you can do any modifications you want. What’s cool about using XmlDataProvider in WPF is that when you change the value of a bound XmlNode inside a user control, the new value will be written to the XmlNode object. That means it supports two-way binding. That makes it extremely easy to edit the summary node in our example. In order to save the changes back to the file system, you just need to call the save method of the underlying XmlDocument:

private void OnSaveClicked(object sender, RoutedEventArgs e)
{
    if(provider != null && provider.Document != null)
    {
        provider.Document.Save(provider.Source.AbsolutePath);
    }
}

Summary
The XmlDataProvider together with WPF binding makes it very easy to access, display, and modify Xml data. You can navigate through the data with just some simple XPath expressions. For small documents it is extremely fast. For larger documents consider loading the document in a background thread and assign it manually to the provider. Always remember  that the XmlDataProvider is just a wrapper around an XmlDocument.