Blog Archives

Google Authenticator

GoogleAuthenticator

 

As promised a while ago I am going to describe the Google Authenticator today. I do not use my own example source code this time. There is a really nice one here that I will explain. Download the source code and get some extra information from this post. This should be enough know-how to use the Google Authenticator in your own application afterwards.

What is the Google Authenticator?
The Google Authenticator is a program that allows time based passwords. It makes the online identification process much safer. You enter your Id, your password and an extra time based password. A third-party can hardly know the time based password. Even if there is a spy program on your PC that reads all your key inputs, then the hacker only has less than 30 seconds to exploit the opportunity. Otherwise he cannot use your credentials. The time component changes constantly. This is a pretty safe approach.
To steal your identity, the hacker needs to get access to the server database and decrypt your information. This is much more difficult than reading your password by using a key Trojan.

What is TOTP?

Once again our example program is using WPF.
The XAML is pretty much straight forward. Each element (TextBlock or Image) is using Binding to the underlying object. Just the Hmac TextBlock is less intuitive. The text consists of 3 TextBlocks, which in fact look like one. The green text is the second TextBlock. There is no method to write all text into one TextBlock and then color it. This would be far more complex than this 3 TextBlock solution.

 

label


property binding


type


Identity Identity string
Secret Secret string
QR code QRCodeUrl Image
Timestamp Timestamp string
Hmac HmacPart1, HmacPart2, HmacPart3 string
One-time password OneTimePassword string
Seconds to go SecondsToGo string

 

The C# source code has some hyperlinks. You should follow them in case you want to learn some detailed background information. You don’t have to do this. To apply the code in your program it should be enough to study and replicate the example source code. This code is really short and I appreciate this a lot. Many programmers make things far more complicated than needed. Are they trying to show off? I don’t know.

Let’s start from the top now.
The DispatcherTimer is the corresponding class for the good old System.Windows.Forms.Timer class. We are not using WinForms anymore. The idea behind the DispatcherTimer is that the timer fires on the Dispatcher thread. This thread is the same that your window is using. Any other thread could freeze your application.
Do not use the System.Threading.Timer class. This class is neither WPF nor WinForms related. It fires on any thread. You must not access WPF elements on arbitrary threads. On the other hand you should use the System.Threading.Timer class in case you do not want to access WPF. Don’t waste precious time of the Dispatcher thread.

The DispatcherTimer fires each 500 ms (=half second) and assigns the actual value of the 30 second countdown to the property SecondsToGo.

The properties Secret and Identity are initialized with arbitrary example data.
Then the DataContext is set. This enables the data binding between the (XAML) window and the (C#) code.

public MainWindow() {
   InitializeComponent();

   var timer = new DispatcherTimer();
   timer.Interval = TimeSpan.FromMilliseconds(500);
   timer.Tick += (s, e) => SecondsToGo = 30 - Convert.ToInt32(GetUnixTimestamp() % 30);
   timer.IsEnabled = true;

   Secret = new byte[] { 0x48, 0x65, 0x6C, 0x6C, 0x6F, 0x21, 0xDE, 0xAD, 0xBE, 0xEF };
   Identity = "user@host.com";

   DataContext = this;
}

You may have noticed already that the MainWindow class implements the interface INotifyPropertyChanged. This exposes a WPF event called PropertyChanged, which is used to notify clients via binding that a property value has changed.

namespace System.ComponentModel {
  public interface INotifyPropertyChanged {
    // Occurs when a property value changes.
    event PropertyChangedEventHandler PropertyChanged;
  }
}

You notify a client (UI) with the property name (string) rather than a delegate.
The standard WPF pattern looks like this:

public event PropertyChangedEventHandler PropertyChanged;  // INotifyPropertyChanged implementation

protected void OnPropertyChanged(string xPropertyName) {
   PropertyChangedEventHandler h = PropertyChanged;
   if (h == null) return;
   h(this, new PropertyChangedEventArgs(xPropertyName));
} //


private string _MyProperty;
public string  MyProperty { 
  get{ return _MyProperty; } 
  set { _MyProperty = value; OnPropertyChanged(“MyProperty”); } 
} //

And here is the source code from the GoogleAuthenticator example:

public event PropertyChangedEventHandler PropertyChanged;

private void OnPropertyChanged(string propertyName) {
 if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

private int _secondsToGo;
public int SecondsToGo {
   get { return _secondsToGo; }
   private set { _secondsToGo = value; OnPropertyChanged("SecondsToGo"); if (SecondsToGo == 30) CalculateOneTimePassword(); }
}

You can find that pattern many times in today’s example source code. Be aware that all properties use the same event, which is PropertyChanged. This makes your code look neat, but on the other hand you unfortunately start working with strings instead of delegates. It is part of the MVVM concept to separate code and GUI. For sure it makes debugging much more difficult and code execution slower.

Just to highlight it again. The Hmac consists of three elements. Therefore the property looks like this:

public byte[] Hmac {
  get { return _hmac; }
  private set { _hmac = value; OnPropertyChanged("Hmac"); OnPropertyChanged("HmacPart1"); OnPropertyChanged("HmacPart2"); OnPropertyChanged("HmacPart3"); }
}

What is an Hmac? To make complex interrelations easier, let’s reduce the Hmac description to “a long calculated key”, which is used to determine our time based password. Therefore to generate the key you need some kind of time input. The other component is a static password (=Secret). I added comments in the following code excerpt:

private void CalculateOneTimePassword() {
  // Get the number of seconds since 1/1/1970 and devide them by 30 seconds.
  // Thus one Timestamp unit is 30 seconds.
  Timestamp = Convert.ToInt64(GetUnixTimestamp() / 30);

  // Convert the 64 bit integer Timestamp to a byte array (8 bytes).
  // eg. ba d9 c7 02 00 00 00 00
  // Then reverse them (=> 00 00 00 00 02 c7 d9 ba) and write the result to the byte array "data".
   var data = BitConverter.GetBytes(Timestamp).Reverse().ToArray();

  // Generate the Hmac key from your password (byte array) and time (byte array).
  Hmac = new HMACSHA1(Secret).ComputeHash(data);

  // Bit-operation: Get the last 4 bits of the Hmac. The results are always equal to or between 0 and 15.
  // The offset determines the area of the Hmac that is used to generate the time based password.
  Offset = Hmac.Last() & 0x0F;

  // The Hmac is 20 bytes long. A block of 4 bytes is used for the OneTimePassword, which changes each 30 seconds.
  // 15 is the highest Offset. Therefore the last used byte is number 18 (first byte is zero based).
  // The 19th (=last) byte is the Offset. More precisely the <a href="http://en.wikipedia.org/wiki/Nibble" title="Wiki Nibble Byte" target="_blank">right nibble</a> of the 19th byte is the Offset value.
  // Bit masks are applied on the selected Hmac block to limit the number. The resulting bits are rotated to the left and added together.
  // Basically we are looking at a manual "bit to integer" conversion.
  // the result is then devided by 1,000,000 and only the remainder is taken. Consequently all results are less than 1,000,000.
  // (The bit mask 0xff is useless. I guess it was used to emphasize the technique for readability purposes. 0x7f does make sense.)
  OneTimePassword = (
         ((Hmac[Offset + 0] & 0x7f) << 24) |
         ((Hmac[Offset + 1] & 0xff) << 16) |
         ((Hmac[Offset + 2] & 0xff) << 8) |
         (Hmac[Offset + 3] & 0xff)) % 1000000;
}

When I looked at the program I was trying to find the bitmap for the QR code. You would expect a method somewhere to convert bytes to an image. But this is not the case.
The GetQRCodeUrl method generates a Url. Follow this Url and you will see that it opens an image in your browser. Google does the work for you.
The programmer of that example code has also added the Url to the description on how to generate such QR code Url. Well done! My advice is to have a quick look at it.

private string GetQRCodeUrl() {
  // https://code.google.com/p/google-authenticator/wiki/KeyUriFormat
  var base32Secret = Base32.Encode(Secret);
  return String.Format("https://www.google.com/chart?chs=200x200&chld=M|0&cht=qr&chl=otpauth://totp/{0}%3Fsecret%3D{1}", Identity, base32Secret);
}

Now we have all bits and pieces to use the Google Authenticator. But how?

1) Ask for a user identification and a password. For instance user “super@man.com” and password “Strong5rThan$trong!”.
2) Convert the password to a byte array.
3) Generate the QR code.
4) The user can scan this QR code with his android cell phone. Press “Set up account” followed by “Scan a barcode” in the Google Authenticator app.
5) The new account appears and updates in the Authenticator app. The Identity and Secret were encoded in the QR code. This is why the app knows your name already.
 
Android
 
6) From now on you can ask for the Id, the password and the time based password.
7) Make sure to have a plan B in place. The user might lose access to his Google Authenticator app. You have to provide a new login then.

Btw. I do know some people, who do not lock their tablet PC or cell phone. The Google Authenticator obviously is not for these kind of people. The problem is not behind the screen … it is in front of the screen.

Advertisements

WPF Control Templates (part 1)

ControlTemplate

Styles and Templates can change the appearance of elements. So what is the difference then?
Templates are far more complex. Styles are mainly adjusting existing properties. You could say that Styles are like Face-Lifting whereas Templates are rather entire face replacements. Elements get new visual trees that can consist of other elements. This is not the case for Styles.

Before we start creating our own templates let’s have a look at the existing standard control templates. Today’s example code reads these Templates from the assembly and prints them in a TextBox.

Take a stroll and get a feeling for them.
Surely this is not for beginners. My advice is to copy, paste and reuse existing professional XAML rather than spending your precious time to figure out every little issue yourself. And today’s source code aims at exactly that approach.

<Application x:Class="WpfTemplates.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             ShutdownMode="OnMainWindowClose"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
         
    </Application.Resources>
</Application>



<Window x:Class="WpfTemplates.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Loaded="Window_Loaded"
        Title="MainWindow" Height="350" Width="525">
    <DockPanel LastChildFill="True">
        <ListBox DockPanel.Dock="Left" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" MinWidth="100" />
        <Grid DockPanel.Dock="Right" Name="dummyGrid" Width="0" />
        <TextBox DockPanel.Dock="Left" Text="{Binding XAML}" TextWrapping="NoWrap" AcceptsReturn="True" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto" FontFamily="Courier New" />
    </DockPanel>
</Window>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Markup;
using System.Xml;

namespace WpfTemplates {
  public partial class MainWindow : Window {

    private class Data {
      public Type Type { get; set; }
      public string XAML { get; set; }

      public Data(Type xType) { this.Type = xType; XAML = "#N/A"; }
      public override string ToString() { return Type.Name; }
    } // class

    public MainWindow() {
      InitializeComponent();
    } //

    private void Window_Loaded(object sender, RoutedEventArgs e) {
      List<Data> lData = new List<Data>();

      Assembly lAssembly = Assembly.GetAssembly(typeof(Control));
      Type lControlType = typeof(Control);
      List<Data> lTypes = (from t in lAssembly.GetTypes().AsParallel()
                           where t.IsSubclassOf(lControlType) && t.IsPublic && !t.IsAbstract
                           orderby t.Name ascending
                           select new Data(t)).ToList();

      InsertXaml(lTypes);
      DataContext = lTypes;
    } //

    private void InsertXaml(List<Data> xTypes) {
      XmlWriterSettings lXmlWriterSettings = new XmlWriterSettings();
      lXmlWriterSettings.Indent = true;
      StringBuilder lStringBuilder = new StringBuilder(); // for output      

      foreach (Data lData in xTypes) {
        try {
          ConstructorInfo lConstructorInfo = lData.Type.GetConstructor(System.Type.EmptyTypes);
          if (lConstructorInfo == null) {
            lData.XAML = lData.Type.Name + " control cannot be instantiated.";
            continue;
          }
          Control lControl = lConstructorInfo.Invoke(null) as Control;  // create an instance
          lControl.Visibility = System.Windows.Visibility.Collapsed;
          bool lIsNullTemplate = (lControl.Template == null);          
          if (lIsNullTemplate) dummyGrid.Children.Add(lControl); // add a collapsed (invisible) control to get access to the template
          ControlTemplate lControlTemplate = lControl.Template; // now not null anymore
          using (XmlWriter lXmlWriter = XmlWriter.Create(lStringBuilder, lXmlWriterSettings)) { // will write to StringBuilder
            XamlWriter.Save(lControlTemplate, lXmlWriter);
            lData.XAML = lStringBuilder.ToString();
          }
          lStringBuilder.Clear();
          if (lIsNullTemplate) dummyGrid.Children.Remove(lControl);
        }
        catch (Exception ex) {
          lData.XAML = lData.Type.Name + " control cannot be added to the grid.\n\nException message:\n" + ex.Message;
        }
      }
    } //

  } // class
} // namespace

WPF Commands (part 2)

Let’s start with a program that uses Cut, Copy and Paste in two TextBoxes without writing any C# code. This is not a typo. We only need XAML for this.

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="400" Width="400">    
    <DockPanel LastChildFill="True" >
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Edit">
                <MenuItem Command="{x:Static ApplicationCommands.Cut}" CommandParameter="Cut it!"/>
                <MenuItem Command="{x:Static ApplicationCommands.Copy}" CommandParameter="Copy it!"/>
                <MenuItem Command="{x:Static ApplicationCommands.Paste}" CommandParameter="Paste it!"/>
            </MenuItem>
        </Menu>     

        <ToolBarTray Background="Gray" DockPanel.Dock="Top">
            <ToolBar Band="0" BandIndex="0" >
                <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
                <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
                <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
            </ToolBar>
            <ToolBar Band="1" BandIndex="1">
                <ToolBarPanel Orientation="Vertical">
                    <Label Content="Dummy0" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy1" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy2" ToolBar.OverflowMode="AsNeeded" />
                </ToolBarPanel>
            </ToolBar>
        </ToolBarTray>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="0" Grid.ColumnSpan="1" Margin="0" >It happened that a Fox caught its tail in a trap, and in struggling to release himself lost all of it but the stump. At first he was ashamed to show himself among his fellow foxes.</TextBox>
            <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,0,0,0" Width="3"/>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="2" Grid.ColumnSpan="1" Margin="0" >But at last he determined to put a bolder face upon his misfortune, and summoned all the foxes to a general meeting to consider a proposal which he had to place before them.</TextBox>
        </Grid>
    </DockPanel>
</Window>

Editor

 

I added a Toolbar with some dummy labels just to keep the learning curve going. You remove them without any risk.

What is happening here?

Some input controls handle command events on their own. Everything is built-in already. All you need to do is to provide the Buttons or MenuItems which call these commands. The elements even enable/disable themselves. We have two textboxes in the example. These commands are applied to the element that has the focus.
How can this be achieved? The element finds the window instance and then determines what element was focused previously. This only works for Toolbars and Menus UNLESS you set the CommandTarget property  manually.

Let’s add standard buttons now. You cannot see any effect when you press them. The buttons are even ghosted. To solve this we assign the names TextBox1 and TextBox2 and link the Button CommandTargets to these elements.

 

NotWorking

 

You can now cut or copy from TextBox1 and paste it into TextBox2.
 

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="400" Width="400">    
    <DockPanel LastChildFill="True" >
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Edit">
                <MenuItem Command="{x:Static ApplicationCommands.Cut}" CommandParameter="Cut"/>
                <MenuItem Command="{x:Static ApplicationCommands.Copy}" CommandParameter="Copy"/>
                <MenuItem Command="{x:Static ApplicationCommands.Paste}" CommandParameter="Paste"/>
            </MenuItem>
        </Menu>     

        <ToolBarTray Background="Gray" DockPanel.Dock="Top">
            <ToolBar Band="0" BandIndex="0" >
                <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
                <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
                <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
            </ToolBar>
            <ToolBar Band="1" BandIndex="1">
                <ToolBarPanel Orientation="Vertical">
                    <Label Content="Dummy0" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy1" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy2" ToolBar.OverflowMode="AsNeeded" />
                </ToolBarPanel>
            </ToolBar>
        </ToolBarTray>
<!-- changed -->
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top">
            <Button Command="{x:Static ApplicationCommands.Cut}" CommandTarget="{Binding ElementName=TextBox1}" Content="Cut" />
            <Button Command="{x:Static ApplicationCommands.Copy}" CommandTarget="{Binding ElementName=TextBox1}" Content="Copy" />
            <Button Command="{x:Static ApplicationCommands.Paste}" CommandTarget="{Binding ElementName=TextBox2}"  Content="Paste" />
        </StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
<!-- changed -->
            <TextBox Name="TextBox1" TextWrapping="Wrap" Width="Auto" Grid.Column="0" Grid.ColumnSpan="1" Margin="0" >It happened that a Fox caught its tail in a trap, and in struggling to release himself lost all of it but the stump. At first he was ashamed to show himself among his fellow foxes.</TextBox>
            <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,0,0,0" Width="3"/>
<!-- changed -->
            <TextBox Name="TextBox2" TextWrapping="Wrap" Width="Auto" Grid.Column="2" Grid.ColumnSpan="1" Margin="0" >But at last he determined to put a bolder face upon his misfortune, and summoned all the foxes to a general meeting to consider a proposal which he had to place before them.</TextBox>
        </Grid>

    </DockPanel>
</Window>

But hardcoding is a really bad approach. Therefore we are going to use FocusManager.IsFocusScope=”True” instead. WPF then checks the parent focus. By default, the Window class is a focus scope as are the Menu, ContextMenu, and ToolBar classes.
The following example is flawless.

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="400" Width="400">    
    <DockPanel LastChildFill="True" >
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Edit">
                <MenuItem Command="{x:Static ApplicationCommands.Cut}" CommandParameter="Cut"/>
                <MenuItem Command="{x:Static ApplicationCommands.Copy}" CommandParameter="Copy"/>
                <MenuItem Command="{x:Static ApplicationCommands.Paste}" CommandParameter="Paste"/>
            </MenuItem>
        </Menu>     

        <ToolBarTray Background="Gray" DockPanel.Dock="Top">
            <ToolBar Band="0" BandIndex="0" >
                <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
                <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
                <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
            </ToolBar>
            <ToolBar Band="1" BandIndex="1">
                <ToolBarPanel Orientation="Vertical">
                    <Label Content="Dummy0" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy1" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy2" ToolBar.OverflowMode="AsNeeded" />
                </ToolBarPanel>
            </ToolBar>
        </ToolBarTray>
<!-- changed -->
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" FocusManager.IsFocusScope="True">
            <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
            <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
            <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
        </StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="0" Grid.ColumnSpan="1" Margin="0" >It happened that a Fox caught its tail in a trap, and in struggling to release himself lost all of it but the stump. At first he was ashamed to show himself among his fellow foxes.</TextBox>
            <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,0,0,0" Width="3"/>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="2" Grid.ColumnSpan="1" Margin="0" >But at last he determined to put a bolder face upon his misfortune, and summoned all the foxes to a general meeting to consider a proposal which he had to place before them.</TextBox>
        </Grid>

    </DockPanel>
</Window>

The IsFocusScope approach has the advantage that the same commands apply to several controls.

 
 
Custom Commands
 

We are going to write our own commands now. For this we need to create a class and add a property that returns a RoutedUICommand instance. This property needs to be static. And to initialize this class you also need a static constructor.

using System.Windows.Input;

namespace CustomCommands {
 
  public class PlaySound {

    static PlaySound() {
      KeyGesture lShortCut = new KeyGesture(Key.P, ModifierKeys.Control, "Ctrl+p");
      InputGestureCollection InputGestureCollection = new InputGestureCollection();
      InputGestureCollection.Add(lShortCut);
      PlaySoundCommand = new RoutedUICommand("Play", "PlaySound", typeof(PlaySound), InputGestureCollection);      
    } // static constructor

    public static RoutedUICommand PlaySoundCommand { get; private set; }
  } // class

} // namespace

The MainWindow class should look like this. The method CommandBinding_PlaySound_Executed plays the system beep sound.

using System.Windows;
using System.Windows.Input;

namespace DemoApp {

  public partial class MainWindow : Window {

    public MainWindow() {
      InitializeComponent();
    }

   private void CommandBinding_PlaySound_Executed(object sender, ExecutedRoutedEventArgs e) {
      System.Media.SystemSounds.Beep.Play();      
      MessageBox.Show("Source: " + e.Source.ToString() + Environment.NewLine + 
        "OriginalSource: " + e.OriginalSource.ToString() + Environment.NewLine + 
        "Parameter: " + e.Parameter.ToString());
    } //

  } // class
} // namespace

Add the class in your XAML namespace. I used xmlns:c=”clr-namespace:CustomCommands” .

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        xmlns:c="clr-namespace:CustomCommands"
        Title="MainWindow" Height="400" Width="400">
<!-- above was changed -->
    <Window.CommandBindings>
<!-- changed -->
        <CommandBinding Command="c:PlaySound.PlaySoundCommand" Executed="CommandBinding_PlaySound_Executed" />
    </Window.CommandBindings>
    <DockPanel LastChildFill="True" >
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Edit">
                <MenuItem Command="{x:Static ApplicationCommands.Cut}" CommandParameter="Cut"/>
                <MenuItem Command="{x:Static ApplicationCommands.Copy}" CommandParameter="Copy"/>
                <MenuItem Command="{x:Static ApplicationCommands.Paste}" CommandParameter="Paste"/>
            </MenuItem>
            <MenuItem Header="_Media">
                <MenuItem Command="c:PlaySound.PlaySoundCommand" CommandParameter="Play"/>
            </MenuItem>
        </Menu>     

        <ToolBarTray Background="Gray" DockPanel.Dock="Top">
            <ToolBar Band="0" BandIndex="0" >
                <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
                <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
                <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
            </ToolBar>
            <ToolBar Band="1" BandIndex="1">
                <ToolBarPanel Orientation="Vertical">
                    <Label Content="Dummy0" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy1" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy2" ToolBar.OverflowMode="AsNeeded" />
                </ToolBarPanel>
            </ToolBar>
        </ToolBarTray>
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" FocusManager.IsFocusScope="True">
            <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
            <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
            <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
<!-- changed -->
            <Button Command="c:PlaySound.PlaySoundCommand" Content="Play" CommandParameter="What a lovely song!" />
        </StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="0" Grid.ColumnSpan="1" Margin="0" >It happened that a Fox caught its tail in a trap, and in struggling to release himself lost all of it but the stump. At first he was ashamed to show himself among his fellow foxes.</TextBox>
            <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,0,0,0" Width="3"/>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="2" Grid.ColumnSpan="1" Margin="0" >But at last he determined to put a bolder face upon his misfortune, and summoned all the foxes to a general meeting to consider a proposal which he had to place before them.</TextBox>
        </Grid>

    </DockPanel>
</Window>

PlaySound

There is a shortcut to calling commands. You can create an ICommand instance and provide it via a property. The downside – what did you expect? – is that you have no shortcut key or any other comfort.

Step 1: Create a class that inherits from interface ICommand.

using System;
using System.Windows.Input;

namespace CustomCommands {

  public class PlaySound2 : ICommand {
    object _DependencyObject;

    public PlaySound2(object xDependencyObject) {
      _DependencyObject = xDependencyObject;
    } // constructor

    public event EventHandler CanExecuteChanged {
      add { CommandManager.RequerySuggested += value; }
      remove { CommandManager.RequerySuggested -= value; }
    } //

    public bool CanExecute(object xParameter) {
      return (DateTime.Now.Second % 2 == 0); // timer based example
    } //

    public void Execute(object xParameter) {
      //_DependencyObject.DoSomething();
      System.Windows.MessageBox.Show("Parameter: " + xParameter.ToString());
      System.Media.SystemSounds.Beep.Play();
    } //


  } // class
} // namespace

Step 2: instantiate that class and provide it via a property. You do not need to expose the class in your MainWindow. You can use any class. Set the DataContext to your class where the property is (or use a precise path that leads to that object).

using CustomCommands;
using System;
using System.Windows;
using System.Windows.Input;

namespace DemoApp {

  public partial class MainWindow : Window {

    public MainWindow() {
      InitializeComponent();
      SimpleExecution = new PlaySound2("dummy");
      DataContext = this;
    }

    private void CommandBinding_PlaySound_Executed(object sender, ExecutedRoutedEventArgs e) {
      System.Media.SystemSounds.Beep.Play();
      MessageBox.Show("Source: " + e.Source.ToString() + Environment.NewLine +
        "OriginalSource: " + e.OriginalSource.ToString() + Environment.NewLine +
        "Parameter: " + e.Parameter.ToString());
    } //

    public ICommand SimpleExecution { get; private set; }

  } // class
} // namespace

Step 3: Bind the command in XAML.

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        xmlns:c="clr-namespace:CustomCommands"
        Title="MainWindow" Height="400" Width="400">
    <Window.CommandBindings>
        <CommandBinding Command="c:PlaySound.PlaySoundCommand" Executed="CommandBinding_PlaySound_Executed" />
    </Window.CommandBindings>
    <DockPanel LastChildFill="True" >
        <Menu DockPanel.Dock="Top">
            <MenuItem Header="_Edit">
                <MenuItem Command="{x:Static ApplicationCommands.Cut}" CommandParameter="Cut"/>
                <MenuItem Command="{x:Static ApplicationCommands.Copy}" CommandParameter="Copy"/>
                <MenuItem Command="{x:Static ApplicationCommands.Paste}" CommandParameter="Paste"/>
            </MenuItem>
            <MenuItem Header="_Media">
                <MenuItem Command="c:PlaySound.PlaySoundCommand" CommandParameter="Play"/>
            </MenuItem>
        </Menu>     

        <ToolBarTray Background="Gray" DockPanel.Dock="Top">
            <ToolBar Band="0" BandIndex="0" >
                <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
                <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
                <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
            </ToolBar>
            <ToolBar Band="1" BandIndex="1">
                <ToolBarPanel Orientation="Vertical">
                    <Label Content="Dummy0" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy1" ToolBar.OverflowMode="AsNeeded" />
                    <Label Content="Dummy2" ToolBar.OverflowMode="AsNeeded" />
                </ToolBarPanel>
            </ToolBar>
        </ToolBarTray>
        <StackPanel Orientation="Horizontal" DockPanel.Dock="Top" FocusManager.IsFocusScope="True">
            <Button Command="{x:Static ApplicationCommands.Cut}" Content="Cut" />
            <Button Command="{x:Static ApplicationCommands.Copy}" Content="Copy" />
            <Button Command="{x:Static ApplicationCommands.Paste}" Content="Paste" />
            <Button Command="c:PlaySound.PlaySoundCommand" Content="Play" CommandParameter="What a lovely song!" />
<!-- changed -->
            <Button Command="{Binding SimpleExecution}" Content="StraightForward" CommandParameter="The German way!" />
       </StackPanel>
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition />
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition />
            </Grid.ColumnDefinitions>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="0" Grid.ColumnSpan="1" Margin="0" >It happened that a Fox caught its tail in a trap, and in struggling to release himself lost all of it but the stump. At first he was ashamed to show himself among his fellow foxes.</TextBox>
            <GridSplitter Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="1,0,0,0" Width="3"/>
            <TextBox TextWrapping="Wrap" Width="Auto" Grid.Column="2" Grid.ColumnSpan="1" Margin="0" >But at last he determined to put a bolder face upon his misfortune, and summoned all the foxes to a general meeting to consider a proposal which he had to place before them.</TextBox>
        </Grid>

    </DockPanel>
</Window>

LastExample

That’s it for today 🙂

WPF Commands (part 1)

Due to personal time limitations I add a shorter post today. Nonetheless this post is vital for programmers without any WPF experience.

Events are fairly low-level and deprecated in WPF to a certain degree. They are against the idea of MVVM, which in simple terms is the separation of code and user interface. The new technology is task based – known as commands. Commands act like glue between the user interface and the code. You can avoid a lot of repetitive event-handling code. They deal with text captions and enabled/disabled state synchronizations. Let’s have a look at the ICommand interface:

namespace System.Windows.Input {

   public interface ICommand {
      event EventHandler CanExecuteChanged;
      bool CanExecute(object parameter);
      void Execute(object parameter);
   } // interface

} // namespace

The interface ICommand is inherited by RoutedCommand and indirectly by RoutedUICommand. RoutedUICommand has an additional descriptive text property, which RoutedCommand does not have. Besides this they are the same. RoutedUICommand inherits from RoutedCommand and is used for commands that display some text in the UI like menu items or tooltips.

namespace System.Windows.Input {

   public class RoutedUICommand : RoutedCommand {
      public RoutedUICommand();
      public RoutedUICommand(string text, string name, Type ownerType);
      public RoutedUICommand(string text, string name, Type ownerType, InputGestureCollection inputGestures);
      public string Text { get; set; }       // Text that describes this command.
   } // class

} // namespace

RoutedCommand is the only class in WPF that inherits from ICommand. All other classes are derived from RoutedCommand. An important feature of RoutedCommand in WPF is the so-called bubbling behavior. When you have a button in a StackPanel, then events will be executed in that order: Button -> StackPanel -> Window. I will keep it simple here and explain that behavior in another posts.

WPF has prebuild commands like Cut, Copy, Paste, Open and Print. There is no code behind these commands. You have to bind them to your code. Bubbling does play a big role here. You could press Ctrl+C to copy a text. The same command could be part of a TextBox and a window menu. The bubbling can be used to place the same command in two different places. The key input triggers the window command and provides enough information to process it.
Prebuild commands define a standard and generally increase code reusability.

Notice that RoutedCommand has its enhanced versions of CanExecute() and Execute():

namespace System.Windows.Input {

   public class RoutedCommand : RoutedCommand {
      public RoutedCommand();
      public RoutedCommand(string name, Type ownerType);
      public RoutedCommand(string name, Type ownerType, InputGestureCollection inputGestures);
      public InputGestureCollection InputGestures { get; }
      public string Name { get; }
      public Type OwnerType { get; }

      public event EventHandler CanExecuteChanged;
      public bool CanExecute(object parameter, IInputElement target);
      public void Execute(object parameter, IInputElement target);
   } // class

} // namespace

This is confusing. You naturally expect the same definition as in ICommand. The answer must be that the interface ICommand is implemented explicitly. Thus the interface method is hidden and can only be accessed indirectly via an interface variable. See below example:

public interface IMyInterface {
    void hello(object o);
} // interface

public class MyClass : IMyInterface {
  public void hello(object i, string s) { }
  void IMyInterface.hello(object o) {}
} // class

static void Main(string[] args) {
  MyClass x = new MyClass();       
  x.hello("abc", "abc");  // interface not accessible
  IMyInterface c = x;
  c.hello("abc");  // class not accessible
}

There are several groups (static classes) of prebuild commands in WPF.
ApplicationCommands provides classical commands that are in most applications (eg. Cut, Copy, Paste, Save, New, Print).
NavigationCommands provide commands for navigation that you know from browsers (eg. BrowseForward, BrowseBack).
EditingCommands are known from text editors (eg. Delete, MoveToDocumentEnd, MoveRightByWord, DecreaseFontSize).
ComponentCommands are used to move the cursor around (some duplicates are in EditingCommands; eg. MoveDown, MoveFocusBack, ExtendSelectionDown).
MediaCommands are self-explanatory (eg. Play, Pause, Record, BoostBass, ChannelDown).

These classes are static, there can only one instance in your application. They all have default keystrokes. For instance Ctrl+C is predefined for Copy. When you bind them to a command source and add that command source to a window, then the key combination becomes active. You don’t even need a visible control. An additional feature is that key combinations of commands are automatically shown in menus.

We had some theory now. Let’s get practical:

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="200">
    <StackPanel>
        <Button Command="{x:Static ApplicationCommands.New}" CommandParameter="NewProjectX" Content="New" FontSize="20" />
    </StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Input;

namespace DemoApp {

  public partial class MainWindow : Window {

    public MainWindow() {
      InitializeComponent();

      CommandBinding lCommandBinding = new CommandBinding(ApplicationCommands.New);
      lCommandBinding.Executed += Button_Pressed;
      CommandBindings.Add(lCommandBinding); // add the binding object to our main "window" instance
    } //

    private void Button_Pressed(object sender, ExecutedRoutedEventArgs e) {
      MessageBox.Show(sender.ToString() + " did send the message: " + e.Parameter.ToString() + Environment.NewLine + "OriginalSource: " + e.OriginalSource);
    } //

  } // class
} // namespace

Window1

Window2

You don’t have to add the command in your C# code. You can add it directly in XAML. This can be more comfortable. Unfortunately there is a downside as well. The IntelliSense support suffers and I personally believe that it is more error-prone.

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="200">
    <Window.CommandBindings>
        <CommandBinding Command="{x:Static ApplicationCommands.New}" Executed="Button_Pressed" />
    </Window.CommandBindings>
    <StackPanel>
        <Button Command="{x:Static ApplicationCommands.New}" CommandParameter="NewProjectX" Content="New" FontSize="20" />
    </StackPanel>
</Window>
using System;
using System.Windows;
using System.Windows.Input;

namespace DemoApp {

  public partial class MainWindow : Window {

    public MainWindow() {
      InitializeComponent();

      //CommandBinding lCommandBinding = new CommandBinding(ApplicationCommands.New);
      //lCommandBinding.Executed += Button_Pressed;
      //CommandBindings.Add(lCommandBinding); // add the binding object to the window
    } //

    private void Button_Pressed(object sender, ExecutedRoutedEventArgs e) {
      MessageBox.Show(sender.ToString() + " did send the message: " + e.Parameter.ToString() + Environment.NewLine + "OriginalSource: " + e.OriginalSource);
    } //

  } // class
} // namespace

The next example adds a menu. The shortcut Ctrl+N is automatically shown. There is a slight change for the button as well. The object content (text) now binds to itself and uses the text from the command. The advantage is that you hardcode less and become more flexible on multi-language support later on.
You don’t have to change anything in the C# source code.

<Window x:Class="DemoApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="200">
    <Window.CommandBindings>
        <CommandBinding Command="{x:Static ApplicationCommands.New}" Executed="Button_Pressed" />
    </Window.CommandBindings>
    <StackPanel>
        <Menu>
            <MenuItem Header="_File">
                <MenuItem Command="{x:Static ApplicationCommands.New}" CommandParameter="NewProject_Y"/>
            </MenuItem>
        </Menu>
        <Separator/>
        <Button Command="{x:Static ApplicationCommands.New}" CommandParameter="NewProject_X" Content="{Binding RelativeSource={RelativeSource Self}, Path=Command.Text}" FontSize="20" />
    </StackPanel>
</Window>

Window3

Window4

Final note: Do not use the old school WinForms like approach anymore:

<Button Click="Button_Click" CommandParameter="NewProject_C" FontSize="20">Click</Button>
private void Button_Click(object sender, RoutedEventArgs e) { MessageBox.Show("Button clicked"); } 

The next post will follow-up on custom commands.

Inversion of Control and Dependency Injection (advanced, Part 1), Programming Patterns

I finally had some time and spent some hours on Inversion of Control (IoC) and Dependency Injection (DI). When I did the same a few weeks ago I did not understand a lot. I got lost on the concept of inversion. I tried to figure out, what the inversion was. This blocked all and I ended up pretty much blank despite nearly an hour of pumping information into my head. When you get lost then you should do it at least properly and at full steam 😉  Well, I finally understood the headline … and the world started making sense again.

 

Why the name “Inversion of Control”? (IoC)

An entirely hardcoded class controls the program execution path. All branches are predetermined. By using interfaces you can decouple theses flows, so that at the time of creation the class does not exactly know what instructions to call next.
Let’s say you are using events. The class, which is raising an event, hands the control over to another class. The subscribing class is in control of the program flow, not the class that raises the event. The subscribing class can subscribe or unsubscribe. The class, which is providing the event, should not have any active control over subscriptions. Hence it is an inversion of control.
By using IoC classes become more encapsulated. Let’s say a perfect class is blind and urgently needs a guide dog. The control can now be taken over by external factors. This inverts the control entirely.
Unit testing uses that mechanism. A container can be used to control classes and change the bindings.

 

What is a container?

The expression “container” is rarely used in C#. The C++ world calls containers what C# calls collections. We have come across containers in my C++ posts. Follow the link for a quick refresher.
To simplify the matter we can call a UnityContainer a dictionary of objects with some additional methods.
This container performs binding between components. For instance it replaces all specific interface declarations by fully instantiated classes without the need to explicitly call any initialization.

 

What is dependency?

The structure of a program is: Input, Calculations, Output. The same generally applies to classes. Let’s say you want to run an analysis of a text file. That analysis class can only function properly if the required text file does exist. The calculations depend on the input. The same applies to the output, which can only run if the calculation was successful.

The input class calls the calculation class, which in turn calls the output class. As we are discussing inversion, let’s decouple the classes and implement events. In this case the output class subscribes to the calculation result event and the calculator subscribes to the input event.

 

What Dependency Injection? (DI)

“Dependency Injection” is a subset of “Inversion of Control”. IoC is a principle, whereas DI is an actual implementation of the principle.
DI is a software design pattern that allows removing hard-coded dependencies. First of all you do not create objects directly; you just describe how they look like. To accomplish this, the pattern uses interfaces or base classes. As the dependency is not hardcoded, the actual object can vary each time. It just needs to fulfill the inheritable pattern of an interface or base class.

public class Car { }   // base class
public class Audi : Car { }
public class BMW : Car { }
public class Exhibition {
   Car StageObject { set; get; }  // assign Audi or BMW as the dependency object of class Exhibition
}

 

Interfaces

What are the benefits of interfaces besides multiple inheritance? Several people can work on different problems simultaneously by using interfaces. One person for instance writes the code for logging to text files and another person writes the code for logging to databases. If both use the same interface definition, then the underlying classes can be easily replaced by each other. Interfaces are like promises to provide predefined class patterns at runtime.
Thus we end up with component separation, which is very useful in unit testing. Interfaces can eliminate unfathomable dependencies if used wisely.

 

Dependency Injection and Unit Testing

When you run unit tests, then you will need input data. But it could be too complex to run the entire program just to test some methods. You would try to only instantiate the minimum requirements. Think of a syringe and inject the data into the test case to create an acceptable environment. This can be difficult in case the program was not structured well. You need to examine the code to find dependencies.

Inversion of Control

 

I will cover some IoC/DI basics today and will follow-up on this after some other posts, which were queuing up in the last weeks:

  • Calling Java from C#
  • Calling C# from Java
  • Implement all Java source code examples of the 15 day series C# to C++
  • WPF Datagrid formatting
  • Google Authenticator
  • create a post index for my blog

 

Dependency Injection

There are several ways to implement dependencies in a class. The easiest way is to have a field that holds a reference to the dependency, which is probably the worst approach you can have in terms of flexibility.

public class Report1 {
 private IDataBase _DB = new DataBase();
} 

Report1 r1 = new Report1(); // dependency DataBase must be figured out by examining the code

 

You can use methods or properties to tell your classes what dependency objects they should use. The best approach though is via constructors. You can hardly miss parameters when trying to call the constructor. Of course bad constructor overloading can jeopardize this concept.

public class Car { }  // base class (instead of an interface)
public class Audi : Car { }
public class BMW : Car { }
public class Exhibition {
   Car StageObject { set; get; }  // assign Audi or BMW as the dependency object of class Exhibition
}

public class Report2 {
   public IDataBase DB { get; private set; }
   public void SetDB(IDataBase xDB) { DB = xDB; }
} 

public class Report3 {
  public IDataBase DB { get; set; }
} 

public class Report4 {
   private IDataBase _DB;
   public Report4(IDataBase xDB) { _DB = xDB; }
} 

DataBase lDB = new DataBase();
Report2 r2 = new Report2(); r2.SetDB(lDB);
Report3 r3 = new Report3(); r3.DB = lDB;
Report4 r4 = new Report4(lDB); 

 
If the world was just like class Report4, then we could more or less end the post here. Unfortunately dependencies are often not that obvious. They are well hidden and you need to read the code thoroughly to build unit tests.
Dependency Injection goes further and the real take off takes place with Moq, which I will explain in the follow-up post.

The following code example was didactically compiled. You don’t need any further information, it should be self-explanatory. You can download unity by following this link or using NuGet.

using System;
using Microsoft.Practices.Unity;

public interface IDataBase {
   void QuerySomething();
} // interface

public interface ITextFile {
   void LoadSomething();
} // interface

public interface INetwork {
   string Text { set; get; }
   void ReceiveSomething();
} // interface

public class Network : INetwork {
   public void ReceiveSomething() { Console.WriteLine("Receiving TCP data ..."); }
   public string Text { set; get; }
} // class

public class DataBase : IDataBase {
   private string _Dummy = "I am doing something.";
   public void QuerySomething() { Console.WriteLine(_Dummy); }
} // class

public class TextFile1 : ITextFile {
   public void LoadSomething() { Console.WriteLine("TF1: Loading something..."); }
} // class

public class TextFile2 : ITextFile {
   public void LoadSomething() { Console.WriteLine("TF2: Loading something..."); }
} // class

public class TextFile3 : ITextFile {
   public void LoadSomething() { Console.WriteLine("TF3: Loading something..."); }
} // class

public class Report5 {
   public string Text = "#N/A";
   private IDataBase _DB;
   public readonly ITextFile TF;
   public IDataBase getDB() { return _DB; }
   public Report5(IDataBase xDB, ITextFile xTextFile) { _DB = xDB; TF = xTextFile; }
} // class

public class Report6 {
   public readonly string Text1;
   public readonly string Text2;
   private readonly ITextFile _TextFile;
   public readonly INetwork Network;
   public Report6(ITextFile xTextFile, INetwork xNetwork, string xText1, string xText2) {
      _TextFile = xTextFile;
      Network = xNetwork;
      Text1 = xText1;
      Text2 = xText2;
   } // constructor
} // class

class Program {

   static void Main(string[] args) {

      UnityContainer lContainer = new UnityContainer(); // using Microsoft.Practices.Unity;  

      Report5 r;

      // insufficient data
      Console.WriteLine("test: insufficient data");
      Console.WriteLine("Registering IDataBase");
      lContainer.RegisterType(typeof(IDataBase), typeof(DataBase)); // whenever someone asks for an IDataBase, then return a new DataBase instance    
      try {
         r = lContainer.Resolve<Report5>(); // throws an exception, because ITextFile is undefined
      }
      catch (Exception ex) { Console.WriteLine(ex.Message); }
      Console.WriteLine();

      // full data
      Console.WriteLine("test: sufficient data");
      Console.WriteLine("Registering ITextFile TF1");
      Console.WriteLine("IDataBase is still registered");
      lContainer.RegisterType(typeof(ITextFile), typeof(TextFile1));
      r = lContainer.Resolve<Report5>();
      Console.WriteLine("type of r.TF is " + r.TF.GetType()); // TextFile1
      r.getDB().QuerySomething();
      r.TF.LoadSomething(); // this is TextFile1
      Console.WriteLine();

      // override a previous type registration with another type
      Console.WriteLine("test: override a previous type registration with another type");
      Console.WriteLine("Registering ITextFile TF2");
      lContainer.RegisterType(typeof(ITextFile), typeof(TextFile2)); // override the first type registration    
      //lContainer.RegisterType<ITextFile, TextFile2>();   // same as lContainer.RegisterType(typeof(ITextFile), typeof(TextFile2));
      r = lContainer.Resolve<Report5>();
      Console.WriteLine("type of r.TF is " + r.TF.GetType()); // TextFile2
      r.getDB().QuerySomething();
      r.TF.LoadSomething(); // this is TextFile2 
      Console.WriteLine();

      // override a previous type registration with an instance
      Console.WriteLine("test: override a previous type registration with an instance");
      Console.WriteLine("Registering an instance of TextFile3");
      ITextFile lTextFile = new TextFile3();
      lContainer.RegisterInstance(lTextFile);
      r = lContainer.Resolve<Report5>();
      Console.WriteLine("type of r.TF is " + r.TF.GetType()); // TextFile3
      r.getDB().QuerySomething();
      r.TF.LoadSomething(); // this is TextFile3 
      Console.WriteLine();

      // using names to register instances
      Console.WriteLine("test: using names to register instances");
      lContainer.RegisterType<Report5, Report5>(); // creates a default class without any name
      Report5 a = new Report5(r.getDB(), r.TF); lContainer.RegisterInstance("A", a); a.Text = "Report A";
      Report5 b = new Report5(r.getDB(), r.TF); lContainer.RegisterInstance("B", b); b.Text = "Report B";

      r = lContainer.Resolve<Report5>("A"); Console.WriteLine("got " + r.Text);
      r = lContainer.Resolve<Report5>("B"); Console.WriteLine("got " + r.Text);
      r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); r.Text = "same instance?";
      r = lContainer.Resolve<Report5>("X"); Console.WriteLine("got " + r.Text);  // new instance
      r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); // new instance
      Console.WriteLine();

      // => HAVE A LOOK AT THE BELOW CONTAINER SNAPSHOT => there are 3 instances for Report5

      // using names to register instances
      Console.WriteLine("test: revision, using the same instance");
      Console.WriteLine("ContainerControlledLifetimeManager: re-use instances (singleton behaviour for objects)");
      lContainer.RegisterType<Report5, Report5>(new ContainerControlledLifetimeManager());
      r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); r.Text = "same instance?";
      r = lContainer.Resolve<Report5>("X"); Console.WriteLine("got " + r.Text);  // new instance
      r = lContainer.Resolve<Report5>(); Console.WriteLine("got " + r.Text); // same instance !!!!!
      Console.WriteLine();

      // constructors with parameters
      lContainer.RegisterType<INetwork, Network>();
      lContainer.RegisterType<ITextFile, TextFile2>();
      Console.WriteLine("test: constructors with parameters");
      ResolverOverride[] lParameters = new ResolverOverride[] { new ParameterOverride("xText1", "Hello "), new ParameterOverride("xText2", "world") };
      Report6 lReport6 = lContainer.Resolve<Report6>(lParameters);
      Console.WriteLine("Report6 text field values are: " + lReport6.Text1 + lReport6.Text2);

      Console.ReadLine();
   } //

} // class

 

instances
 

example output:
test: insufficient data
Registering IDataBase
Resolution of the dependency failed, type = “Report5”, name = “(none)”.
Exception occurred while: while resolving.
Exception is: InvalidOperationException – The type ITextFile does not have an ac
cessible constructor.
———————————————–
At the time of the exception, the container was:

Resolving Report5,(none)
Resolving parameter “xTextFile” of constructor Report5(IDataBase xDB, ITextFil
e xTextFile)
Resolving ITextFile,(none)

test: sufficient data
Registering ITextFile TF1
IDataBase is still registered
type of r.TF is TextFile1
I am doing something.
TF1: Loading something…

test: override a previous type registration with another type
Registering ITextFile TF2
type of r.TF is TextFile2
I am doing something.
TF2: Loading something…

test: override a previous type registration with an instance
Registering an instance of TextFile3
type of r.TF is TextFile3
I am doing something.
TF3: Loading something…

test: using names to register instances
got Report A
got Report B
got #N/A
got #N/A
got #N/A

test: revision, using the same instance
ContainerControlledLifetimeManager: re-use instances (singleton behaviour for ob
jects)
got #N/A
got #N/A
got same instance?

test: constructors with parameters
Report6 text field values are: Hello world

Data Binding (part 2, advanced), WPF

The new C++ posts will take a lot time. The C# posts are shorter for the next three weeks. Today I created a DataGrid and three TextBoxes. They are all linked together with pretty much no code. You can even add new items to the list. Check it out!

<Window x:Class="WpfDatabinding2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="26*" />
            <ColumnDefinition Width="192*" />
            <ColumnDefinition Width="285*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="10*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <DataGrid AutoGenerateColumns="True" Grid.ColumnSpan="3" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" ColumnHeaderHeight="30">            
        </DataGrid>
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name}" />
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Owner}" />
        <TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Age}" />
    </Grid>
</Window>
using System.Collections.Generic;
using System.Windows;
using System.Windows.Documents;

namespace WpfDatabinding2 {  

   public partial class MainWindow : Window {
      public class Dog {
         public string Name { get; set; }
         public double Age { get; set; }
         public string Owner { get; set; }
      } // class

      public MainWindow() {
         InitializeComponent();

         List<Dog> lDogs = new List<Dog>();
         lDogs.Add(new Dog() { Name = "Spike", Owner = "Granny", Age = 12.6 });
         lDogs.Add(new Dog() { Name = "Pluto", Owner = "Mickey Mouse", Age = 7.0 });
         lDogs.Add(new Dog() { Name = "Snoopy", Owner = "Charlie Brown", Age = 5.3 });
         lDogs.Add(new Dog() { Name = "Lassie", Owner = "Rudd Weatherwax", Age = 8.5 });

         this.DataContext = lDogs;
      } //

   } // class
} // namespace

Hard to believe, but this is it. Code does not have to be long to be powerful. The magic mostly comes from these lines:

<DataGrid AutoGenerateColumns="True" Grid.ColumnSpan="3" ItemsSource="{Binding}" IsSynchronizedWithCurrentItem="True" ColumnHeaderHeight="30">            
</DataGrid>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Name}" />
<TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Owner}" />
<TextBox Grid.Column="1" Grid.Row="3" Text="{Binding Age}" />

Data Binding (part 1, advanced), WPF

I was studying the “Google Authentication” as I plan to write a post about it. But then I came across the WPF data binding, which I was avoiding so far, because code pieces are not easy to display in posts due to their complexity. The “Google Authentication” source code will use WPF data binding. It therefore makes sense to post about WPF data binding first. Newbies have problems with WPF. It can be quite overwhelming at the beginning. This post is not covering the basics. I expect them to be known already. I will only concentrate on some data binding with TextBoxes today.

Have a look at the XAML:

<Window x:Class="WpfDatabinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        Title="MainWindow" Height="194" Width="374">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Label Grid.Column="0" Grid.Row="0" Content="Value1, Init only" VerticalAlignment="Center" />
        <TextBox Grid.Column=" 1" Grid.Row="0" VerticalAlignment="Center" Text="{Binding Value1, Mode=OneTime}" />

        <Label Grid.Column="0" Grid.Row="1" Content="Value1, OneWay" VerticalAlignment="Center" />
        <TextBox Grid.Column=" 1" Grid.Row="1" VerticalAlignment="Center" Text="{Binding Value1, Mode=OneWay}" />        

        <Label Grid.Column="0" Grid.Row="2" Content="Value2, OneWayToSource" VerticalAlignment="Center" />
        <TextBox Grid.Column=" 1" Grid.Row="2" Text="{Binding Value2, Mode=OneWayToSource}" VerticalAlignment="Center" />

        <Label Grid.Column="0" Grid.Row="3" Content="Value3, OneWay" VerticalAlignment="Center" />
        <TextBox Grid.Column=" 1" Grid.Row="3" Text="{Binding Value3, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" />
        
        <Label Grid.Column="0" Grid.Row="4" Content="Value3, TwoWay" VerticalAlignment="Center" />
        <TextBox Grid.Column=" 1" Grid.Row="4" Text="{Binding Value3, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" />

        <Label Grid.Column="0" Grid.Row="5" Content="Value3, TwoWay" VerticalAlignment="Center" />
        <TextBox Grid.Column=" 1" Grid.Row="5" Text="{Binding Value3, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" VerticalAlignment="Center" />
    </Grid>
</Window>

Instead of assigning simple text literals to the TextBoxes like: Text=”Hello World!”, we assign binding definitions in curly brackets. For instance: Text=”{Binding Value2, Mode=OneWayToSource}”
In this case we connect the property “Value2” with the TextBox text. The Mode tells the binding direction:

Mode

The UpdateSourceTrigger=PropertyChanged implies that the binding source class has implemented the interface INotifyPropertyChanged, which requires the event implementation called PropertyChanged. When the program raises this event with the correct property name, which is also defined in the XAML file, then the binding will refresh the GUI element.

And here is the program. Create a BindingClass instance and assign it to the current window DataContext. There is nothing else to do. The rest is taken care of by the .Net Framework and compiler. WPF is quite abstract. A lot of code is generated out of the XAML files. You cannot see the generated code without pressing the icon “Show All Files” in the Solution Explorer. What is important to know is that we are mainly looking at partial files (here: “public partial class MainWindow : Window”). The rest is auto-generated source code.

using System.Windows;

namespace WpfDatabinding {
   public partial class MainWindow : Window {

      public MainWindow() {
         InitializeComponent();
         DataContext = new BindingClass();
      } //

   } // class
} // namespace
using System;
using System.ComponentModel;
using System.Timers;

namespace WpfDatabinding {
   public class BindingClass : INotifyPropertyChanged {
      public event PropertyChangedEventHandler PropertyChanged;

      private string _Value1 = "Value1 XX:XX:XX";
      private string _Value2 = "Value2 XX:XX:XX";
      private string _Value3 = "Value3 XX:XX:XX";

      public string Value1 { get { return _Value1; } set { _Value1 = value; RaiseEvent("Value1"); } }
      public string Value2 { get { return _Value2; } set { _Value2 = value; RaiseEvent("Value2"); Console.WriteLine(_Value2); } } // event has no effect
      public string Value3 { get { return _Value3; } set { _Value3 = value; RaiseEvent("Value3"); } } // event has effect on TwoWay

      public BindingClass() {
         Timer lTimer = new Timer(1000.0);
         lTimer.Elapsed += new ElapsedEventHandler(Timer_Elapsed);
         lTimer.Start();
      } // constructor

      void Timer_Elapsed(object sender, ElapsedEventArgs e) {
         string lNow = DateTime.Now.ToString("HH:mm:ss");
         Value1 = "Value1 " + lNow;
      } // 

      private void RaiseEvent(string xPropertyName) {
         var lEvent = PropertyChanged;
         if (lEvent == null) return;
         lEvent(this, new PropertyChangedEventArgs(xPropertyName));
      } //

   } // class
} // namespace

The BindingClass is straight forward. There are no events that are triggered by the GUI. The separation of XAML and program code is a pretty cool approach.
There are three properties: Value1, Value2 and Value3.
Value1 is constantly written to by a timer event that is raised each second.
Value2 is only receiving values from the GUI, because the corresponding TextBox is using Mode=OneWayToSource. This does not print anything in the GUI, hence I added the Console.WriteLine(_Value2) statement. Check the output there. The statement RaiseEvent("Value2") has no impact, writing to a TextBox would be the wrong direction for this mode.
And RaiseEvent("Value3") only impacts TwoWay TextBoxes, but not on the OneWay TextBox.
Play with the textboxes and see what reacts on what. My hint is that the last three TextBoxes are the most interesting ones.

WpfDataBinding

example output on the console window:
What happens with Value 2 ?

Protocol Buffers (part 3, advanced), Tcp Networking

Ok guys, hardcore. Unfortunately in a different way than I thought 😉
Once again it took a lot of time to prepare the next source code example. It extends the code of my last post.

I removed the ProtoType class, because inheritance is not a real strength of Protobuf-Net. It is possible, but the ease of code maintenance is a definite argument against it. The complexity increases slowly, we cannot afford code that is difficult to change.

In theory we could write a Serialize() method for each class, the result would be extreme performance. You could use the BitConverter class to convert and then merge values without causing too much overhead. And by using Assembler I guess you could even make it 10 times faster again.

I think that all modern protocols lose a lot of time due to the required reflection, which is mainly the mapping of methods and properties. And unlike Assembler the modern languages do not allow to eg. simply write an integer to a memory address and only read the first byte of it.
You can rotate bits or multiply and divide, what is much less efficient.

In C# you can use the Parallel class to boost your performance. Of course the processing time of each code piece has to be substantial, otherwise it takes longer to create tasks than to solve the problems. In slow networks it might even be worth considering packing data before it is sent.

I replaced the ProtoType class by the Header class, which tells the type of the succeeding data block and also adds a serial identifier. This identifier can be used to receive vital feedbacks. For instance the server tells the client if the data transmission was successful or not. It can also send calculation results or error messages.

The data stream has the following order: header, data, header, data, header, data … except for feedback headers; they do not need data blocks. The enum eType inside the Header class defines all possible data types: ErrorMessage, Feedback, Book or Fable.
As said before I did not use inheritance for the Header class. The code remains legible and there is no spaghetti code to achieve indirect multiple inheritance.

In my last post, the client was sending and the server was receiving data. Now the communication is bidirectional. The client uses two threads, one to send and one to receive. The sending method is still using the BlockingCollection construction and an endless loop on a separate thread.
The server can be connected to several clients simultaneously. To keep it simple I decided sending data without any context switching. This usually blocks threads during the IO operation. I have added tasks inside the event OnMessageBook to give an example on how to avoid this. Nevertheless the send method uses a lock on the client preventing simultaneous write actions on the socket. This is bad practice; you should not apply locks on objects that might be locked in other areas as well. This is out of your scope, you don’t know if the .Net framework or any other code uses a lock on the same object, which could cause undesired behavior. In the below example it would have been better to wrap the client object into another class and apply the lock on that outer shell object. But I guess this is ok in our shorter example. The code was long enough already.

public static void Send(TcpClient xClient, ProtoBufExample.Header xHeader) {
  if (xHeader == null) return;
  if (xClient == null) return;

  lock (xClient) {
     NetworkStream lNetworkStream = xClient.GetStream();
  ....

The above lock problem could be avoided with this:

public class ClientData {
   public TcpClient Client { get; private set; }
   private DateTime _ConnectedSince;
   private string _UserName;
   ....

public static void Send(ClientData xClient, ProtoBufExample.Header xHeader) {
  if (xHeader == null) return;
  if (xClient == null) return;

  lock (xClient) {
     NetworkStream lNetworkStream = xClient.Client.GetStream();
  ....

And here is the entire source code:

using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using ProtoBuf;

namespace DemoApp {

   public class ProtoBufExample {

      public enum eType : byte { eError = 0, eFeedback, eBook, eFable };

      [ProtoContract]
      public class Header {
         [ProtoMember(1)] public eType objectType;
         [ProtoMember(2)] public readonly int serialMessageId;

         public object data;
         private static int _HeaderSerialId = 0;

         public Header(object xData, eType xObjectType, int xSerialMessageId = 0) {
            data = xData;
            serialMessageId = (xSerialMessageId == 0) ? Interlocked.Increment(ref _HeaderSerialId) : xSerialMessageId;
            objectType = xObjectType; // we could use "if typeof(T) ...", but it would be slower, harder to maintain and less legible
         } // constructor

         // parameterless constructor needed for Protobuf-net
         public Header() {
         } // constructor

      } // class

      [ProtoContract]
      public class ErrorMessage {
         [ProtoMember(1)]
         public string Text;
      } // class

      [ProtoContract]
      public class Book {
         [ProtoMember(1)] public string author;
         [ProtoMember(2, DataFormat = DataFormat.Group)] public List<Fable> stories;
         [ProtoMember(3)] public DateTime edition;
         [ProtoMember(4)] public int pages;
         [ProtoMember(5)] public double price;
         [ProtoMember(6)] public bool isEbook;

         public override string ToString() {
            StringBuilder s = new StringBuilder();
            s.Append("by "); s.Append(author);
            s.Append(", edition "); s.Append(edition.ToString("dd MMM yyyy"));
            s.Append(", pages "); s.Append(pages);
            s.Append(", price "); s.Append(price);
            s.Append(", isEbook "); s.Append(isEbook);
            s.AppendLine();
            if (stories != null) foreach (Fable lFable in stories) {
                  s.Append("title "); s.Append(lFable.title);
                  s.Append(", rating "); s.Append(lFable.customerRatings.Average()); // Average() is an extension method of "using System.Linq;"
                  s.AppendLine();
               }

            return s.ToString();
         } //
      } // class

      [ProtoContract]
      public class Fable {
         [ProtoMember(1)] public string title;
         [ProtoMember(2, DataFormat = DataFormat.Group)]
         public double[] customerRatings;

         public override string ToString() {
            return "title " + title + ", rating " + customerRatings.Average();
         } //
      } // class

      public static Book GetData() {
         return new Book {
            author = "Aesop",
            price = 1.99,
            isEbook = false,
            edition = new DateTime(1975, 03, 13),
            pages = 203,
            stories = new List<Fable>(new Fable[] {
                new Fable{ title = "The Fox & the Grapes", customerRatings = new double[]{ 0.7, 0.7, 0.8} },
                new Fable{ title = "The Goose that Laid the Golden Eggs", customerRatings = new double[]{ 0.6, 0.75, 0.5, 1.0} },
                new Fable{ title = "The Cat & the Mice", customerRatings = new double[]{ 0.1, 0.0, 0.3} },
                new Fable{ title = "The Mischievous Dog", customerRatings = new double[]{ 0.45, 0.5, 0.4, 0.0, 0.5} }
            })
         };
      } //
   } // class

   public class PendingFeedbacks {
      private readonly ConcurrentDictionary<int, ProtoBufExample.Header> _Messages = new ConcurrentDictionary<int, ProtoBufExample.Header>();

      public int Count { get { return _Messages.Count; } }

      public void Add(ProtoBufExample.Header xHeader) {
         if (xHeader == null) throw new Exception("cannot add a null header");

         if (!_Messages.TryAdd(xHeader.serialMessageId, xHeader)) {
            throw new Exception("there must be a programming error somewhere");
         }
      } //

      public void Remove(ProtoBufExample.Header xHeader) {
         ProtoBufExample.Header lHeader;
         if (!_Messages.TryRemove(xHeader.serialMessageId, out lHeader)) {
            throw new Exception("there must be a programming error somewhere");
         }

         switch (xHeader.objectType) {
            case ProtoBufExample.eType.eError:
               Console.WriteLine("error: " + ((ProtoBufExample.ErrorMessage)xHeader.data).Text);
               Console.WriteLine("the message that was sent out was: " + lHeader.objectType + " with serial id " + lHeader.serialMessageId);
               Console.WriteLine("please check the log files" + Environment.NewLine);
               break;
            case ProtoBufExample.eType.eFeedback:
               // all ok !
               break;
            default:
               Console.WriteLine("warning: This message type was not expected.");
               break;
         }
      } //
   } // class

   public static class NetworkTest {
      public static void Test() {
         NetworkListener lServer = new NetworkListener("127.0.0.1", 65432, "Server");
         NetworkClient lClient = new NetworkClient("127.0.0.1", 65432, "Client");

         lServer.Connect();
         lServer.OnMessageBook += new NetworkListener.dOnMessageBook(OnMessageBook);
         lServer.OnMessageFable += new NetworkListener.dOnMessageFable(OnMessageFable);

         lClient.Connect();

         ProtoBufExample.Header lHeader;

         // send a book across the network
         ProtoBufExample.Book lBook = ProtoBufExample.GetData();
         lHeader = new ProtoBufExample.Header(lBook, ProtoBufExample.eType.eBook);
         lClient.Send(lHeader);

         System.Threading.Thread.Sleep(1000);  // remove this to see the asynchonous processing (the output will look terrible)

         // send a fable across the network
         lHeader = new ProtoBufExample.Header(lBook.stories[1], ProtoBufExample.eType.eFable);
         lClient.Send(lHeader);

         System.Threading.Thread.Sleep(1000);

         lClient.Disconnect();
         lServer.Disconnect();

         Console.ReadLine();
      }

      // demo: synchronous processing
      static void OnMessageFable(TcpClient xSender, ProtoBufExample.Header xHeader, ProtoBufExample.Fable xFable) {
         Console.WriteLine(Environment.NewLine + "received a fable: ");
         Console.WriteLine(xFable.ToString());

         // demo: we tell the server that something went wrong
         ProtoBufExample.ErrorMessage lErrorMessage = new ProtoBufExample.ErrorMessage() { Text = "The fable was rejected. It is far too short." };
         ProtoBufExample.Header lErrorHeader = new ProtoBufExample.Header(lErrorMessage, ProtoBufExample.eType.eError, xHeader.serialMessageId);
         NetworkListener.Send(xSender, lErrorHeader);
      } //

      // demo: asynchronous processing
      static void OnMessageBook(TcpClient xSender, ProtoBufExample.Header xHeader, ProtoBufExample.Book xBook) {
         Task.Factory.StartNew(() => {
            Console.WriteLine(Environment.NewLine + "received a book: ");
            Console.WriteLine(xBook.ToString());

            // send a feedback without any body to signal all was ok
            ProtoBufExample.Header lFeedback = new ProtoBufExample.Header(null, ProtoBufExample.eType.eFeedback, xHeader.serialMessageId);
            NetworkListener.Send(xSender, lFeedback);
            return;
         });

         Console.WriteLine("Book event was raised");
      } //

   } // class

   public class NetworkListener {

      private bool _ExitLoop = true;
      private TcpListener _Listener;

      public delegate void dOnMessageBook(TcpClient xSender, ProtoBufExample.Header xHeader, ProtoBufExample.Book xBook);
      public event dOnMessageBook OnMessageBook;

      public delegate void dOnMessageFable(TcpClient xSender, ProtoBufExample.Header xHeader, ProtoBufExample.Fable xFable);
      public event dOnMessageFable OnMessageFable;

      private List<TcpClient> _Clients = new List<TcpClient>();

      public int Port { get; private set; }
      public string IpAddress { get; private set; }
      public string ThreadName { get; private set; }

      public NetworkListener(string xIpAddress, int xPort, string xThreadName) {
         Port = xPort;
         IpAddress = xIpAddress;
         ThreadName = xThreadName;
      } //

      public bool Connect() {
         if (!_ExitLoop) {
            Console.WriteLine("Listener running already");
            return false;
         }
         _ExitLoop = false;

         try {
            _Listener = new TcpListener(IPAddress.Parse(IpAddress), Port);
            _Listener.Start();

            Thread lThread = new Thread(new ThreadStart(LoopWaitingForClientsToConnect));
            lThread.IsBackground = true;
            lThread.Name = ThreadName + "WaitingForClients";
            lThread.Start();

            return true;
         }
         catch (Exception ex) { Console.WriteLine(ex.Message); }
         return false;
      } //

      public void Disconnect() {
         _ExitLoop = true;
         lock (_Clients) {
            foreach (TcpClient lClient in _Clients) lClient.Close();
            _Clients.Clear();
         }
      } //        

      private void LoopWaitingForClientsToConnect() {
         try {
            while (!_ExitLoop) {
               Console.WriteLine("waiting for a client");
               TcpClient lClient = _Listener.AcceptTcpClient();
               string lClientIpAddress = lClient.Client.LocalEndPoint.ToString();
               Console.WriteLine("new client connecting: " + lClientIpAddress);
               if (_ExitLoop) break;
               lock (_Clients) _Clients.Add(lClient);

               Thread lThread = new Thread(new ParameterizedThreadStart(LoopRead));
               lThread.IsBackground = true;
               lThread.Name = ThreadName + "CommunicatingWithClient";
               lThread.Start(lClient);
            }
         }
         catch (Exception ex) { Console.WriteLine(ex.Message); }
         finally {
            _ExitLoop = true;
            if (_Listener != null) _Listener.Stop();
         }
      } // 

      private void LoopRead(object xClient) {
         TcpClient lClient = xClient as TcpClient;
         NetworkStream lNetworkStream = lClient.GetStream();

         while (!_ExitLoop) {
            try {
               ProtoBufExample.Header lHeader = ProtoBuf.Serializer.DeserializeWithLengthPrefix<ProtoBufExample.Header>(lNetworkStream, ProtoBuf.PrefixStyle.Fixed32);
               if (lHeader == null) break; // happens during shutdown process
               switch (lHeader.objectType) {

                  case ProtoBufExample.eType.eBook:
                     ProtoBufExample.Book lBook = ProtoBuf.Serializer.DeserializeWithLengthPrefix<ProtoBufExample.Book>(lNetworkStream, ProtoBuf.PrefixStyle.Fixed32);
                     if (lBook == null) break;
                     lHeader.data = lBook; // not necessary, but nicer                            

                     dOnMessageBook lEventBook = OnMessageBook;
                     if (lEventBook == null) continue;
                     lEventBook(lClient, lHeader, lBook);
                     break;

                  case ProtoBufExample.eType.eFable:
                     ProtoBufExample.Fable lFable = ProtoBuf.Serializer.DeserializeWithLengthPrefix<ProtoBufExample.Fable>(lNetworkStream, ProtoBuf.PrefixStyle.Fixed32);
                     if (lFable == null) break;
                     lHeader.data = lFable; // not necessary, but nicer                            

                     dOnMessageFable lEventFable = OnMessageFable;
                     if (lEventFable == null) continue;
                     lEventFable(lClient, lHeader, lFable);
                     break;

                  default:
                     Console.WriteLine("Mayday, mayday, we are in big trouble.");
                     break;
               }
            }
            catch (System.IO.IOException) {
               if (_ExitLoop) Console.WriteLine("user requested client shutdown");
               else Console.WriteLine("disconnected");
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
         }
         Console.WriteLine("server: listener is shutting down");
      } //

      public static void Send(TcpClient xClient, ProtoBufExample.Header xHeader) {
         if (xHeader == null) return;
         if (xClient == null) return;

         lock (xClient) {
            try {
               NetworkStream lNetworkStream = xClient.GetStream();

               // send header (most likely a simple feedback)
               ProtoBuf.Serializer.SerializeWithLengthPrefix<ProtoBufExample.Header>(lNetworkStream, xHeader, ProtoBuf.PrefixStyle.Fixed32);

               // send errors
               if (xHeader.objectType != ProtoBufExample.eType.eError) return;
               ProtoBuf.Serializer.SerializeWithLengthPrefix<ProtoBufExample.ErrorMessage>(lNetworkStream, (ProtoBufExample.ErrorMessage)xHeader.data, ProtoBuf.PrefixStyle.Fixed32);
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
         }

      } //

   } // class

   public class NetworkClient {
      public int Port { get; private set; }
      public string IpAddress { get; private set; }
      public string ThreadName { get; private set; }
      private NetworkStream _NetworkStream = null;
      private TcpClient _Client = null;
      private bool _ExitLoop = true;
      private BlockingCollection<ProtoBufExample.Header> _Queue = new BlockingCollection<ProtoBufExample.Header>();
      private readonly PendingFeedbacks _PendingFeedbacks = new PendingFeedbacks();

      public NetworkClient(string xIpAddress, int xPort, string xThreadName) {
         Port = xPort;
         IpAddress = xIpAddress;
         ThreadName = xThreadName;
      } //

      public void Connect() {
         if (!_ExitLoop) return; // running already
         _ExitLoop = false;

         _Client = new TcpClient();
         _Client.Connect(IpAddress, Port);
         _NetworkStream = _Client.GetStream();

         Thread lLoopWrite = new Thread(new ThreadStart(LoopWrite));
         lLoopWrite.IsBackground = true;
         lLoopWrite.Name = ThreadName + "Write";
         lLoopWrite.Start();

         Thread lLoopRead = new Thread(new ThreadStart(LoopRead));
         lLoopRead.IsBackground = true;
         lLoopRead.Name = ThreadName + "Read";
         lLoopRead.Start();
      } //

      public void Disconnect() {
         _ExitLoop = true;
         _Queue.Add(null);
         if (_Client != null) _Client.Close();
         //if (_NetworkStream != null) _NetworkStream.Close();
      } //

      public void Send(ProtoBufExample.Header xHeader) {
         if (xHeader == null) return;
         _PendingFeedbacks.Add(xHeader);
         _Queue.Add(xHeader);
      } //


      private void LoopWrite() {
         while (!_ExitLoop) {
            try {
               ProtoBufExample.Header lHeader = _Queue.Take();
               if (lHeader == null) break;

               // send header
               ProtoBuf.Serializer.SerializeWithLengthPrefix<ProtoBufExample.Header>(_NetworkStream, lHeader, ProtoBuf.PrefixStyle.Fixed32);

               // send data
               switch (lHeader.objectType) {
                  case ProtoBufExample.eType.eBook:
                     ProtoBuf.Serializer.SerializeWithLengthPrefix<ProtoBufExample.Book>(_NetworkStream, (ProtoBufExample.Book)lHeader.data, ProtoBuf.PrefixStyle.Fixed32);
                     break;
                  case ProtoBufExample.eType.eFable:
                     ProtoBuf.Serializer.SerializeWithLengthPrefix<ProtoBufExample.Fable>(_NetworkStream, (ProtoBufExample.Fable)lHeader.data, ProtoBuf.PrefixStyle.Fixed32);
                     break;
                  default:
                     break;
               }
            }
            catch (System.IO.IOException) {
               if (_ExitLoop) Console.WriteLine("user requested client shutdown.");
               else Console.WriteLine("disconnected");
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
         }
         _ExitLoop = true;
         Console.WriteLine("client: writer is shutting down");
      } //


      private void LoopRead() {
         while (!_ExitLoop) {
            try {
               ProtoBufExample.Header lHeader = ProtoBuf.Serializer.DeserializeWithLengthPrefix<ProtoBufExample.Header>(_NetworkStream, ProtoBuf.PrefixStyle.Fixed32);
               if (lHeader == null) break;
               if (lHeader.objectType == ProtoBufExample.eType.eError) {
                  ProtoBufExample.ErrorMessage lErrorMessage = ProtoBuf.Serializer.DeserializeWithLengthPrefix<ProtoBufExample.ErrorMessage>(_NetworkStream, ProtoBuf.PrefixStyle.Fixed32);
                  lHeader.data = lErrorMessage;
               }
               _PendingFeedbacks.Remove(lHeader);
            }
            catch (System.IO.IOException) {
               if (_ExitLoop) Console.WriteLine("user requested client shutdown");
               else Console.WriteLine("disconnected");
            }
            catch (Exception ex) { Console.WriteLine(ex.Message); }
         }
         Console.WriteLine("client: reader is shutting down");
      } //

   } // class

} // namespace

example output:
waiting for a client
new client connecting: 127.0.0.1:65432
waiting for a client
Book event was raised

received a book:
by Aesop, edition 13 Mar 1975, pages 203, price 1.99, isEbook False
title The Fox & the Grapes, rating 0.733333333333333
title The Goose that Laid the Golden Eggs, rating 0.7125
title The Cat & the Mice, rating 0.133333333333333
title The Mischievous Dog, rating 0.37

received a fable:
title The Goose that Laid the Golden Eggs, rating 0.7125
error: The fable was rejected. It is far too short.
the message that was sent out was: eFable with serial id 2
please check the log files

client: writer is shutting down
server: listener is shutting down
user requested client shutdown
client: reader is shutting down

Reflection (part 5, professional), CodeDOM (& lambda expression tree)

Today’s post is about code generation at runtime using CodeDOM, which is the logical step before runtime code generation using Emit. The .Net framework has been built in an amazing way. We can easily neglect some flaws. Compared to Java there are no flaws at all. Jealousy needs to be deserved, sympathy is for free. Somehow Java is for free, and this is what you get.

Make sure, you are aware of the following differences. There are Expression and Statement. Please follow the links if you feel uncertain about the definitions.

Expression
An expression is a sequence of one or more operands and zero or more operators that can be evaluated to a single value, object, method, or namespace.

Statement
The actions that a program takes are expressed in statements. Common actions include declaring variables, assigning values, calling methods, looping through collections, and branching to one or another block of code, depending on a given condition. The order in which statements are executed in a program is called the flow of control or flow of execution.
A statement can consist of a single line of code that ends in a semicolon, or a series of single-line statements in a block. A statement block is enclosed in {} brackets and can contain nested blocks.

Succinct:
An Expression is a kind of mathematical or logical expression.
A Statement is a single code instruction or block of code to execute.

The first example code generates source code for C# and VB and saves the generated files on your desktop. Of course it has to be the classical “hello world” program.
CodeDOM stands for Code Document Object Model. It is located in the System.CodeDom namespace and provides methods to create code at runtime.

// what you need for the code example:
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using Microsoft.CSharp;
using Microsoft.VisualBasic;

First of all you have to create a compile unit object CodeCompileUnit. It is the top container for namespaces, classes and members. Then add the components as follows:

public static void Test() {
    CodeCompileUnit lUnit = new CodeCompileUnit();

    CodeNamespace lNamespace = new CodeNamespace("MyNamespace");
    lNamespace.Imports.Add(new CodeNamespaceImport("System"));
    lNamespace.Imports.Add(new CodeNamespaceImport("System.IO"));     // not used, just for demo
    lUnit.Namespaces.Add(lNamespace);

    CodeTypeDeclaration lClass = new CodeTypeDeclaration("MyClass");
    CodeMethodInvokeExpression lExpression = new CodeMethodInvokeExpression(new CodeTypeReferenceExpression("Console"), "WriteLine", new CodePrimitiveExpression("hello world !"));
    lNamespace.Types.Add(lClass);

    // write Main entry point method
    CodeEntryPointMethod lMain = new CodeEntryPointMethod();
    lMain.Statements.Add(lExpression);
    lClass.Members.Add(lMain);

    // write another method
    CodeMemberMethod lMethod = new CodeMemberMethod();
    lMethod.Name = "DoSomething";
    lClass.Members.Add(lMethod);

    string lDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\";
    CodeGeneratorOptions lOptions = new CodeGeneratorOptions();
    lOptions.IndentString = "  "; // or "\t";
    lOptions.BlankLinesBetweenMembers = true;

    // generate a C# source code file
    CSharpCodeProvider lCSharpCodeProvider = new CSharpCodeProvider();
    using (StreamWriter lStreamWriter = new StreamWriter(lDesktopPath + "HelloWorld.cs", false)) {
        lCSharpCodeProvider.GenerateCodeFromCompileUnit(lUnit, lStreamWriter, lOptions);
    }

    // generate a VB source code file
    VBCodeProvider lVBCodeProvider = new VBCodeProvider();
    using (StreamWriter lStreamWriter = new StreamWriter(lDesktopPath + "HelloWorld.vb", false)) {
        lVBCodeProvider.GenerateCodeFromCompileUnit(lUnit, lStreamWriter, lOptions);
    }
            
} //

example output file HelloWorld.cs:

//------------------------------------------------------------------------------
// 
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18408
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

namespace MyNamespace {
  using System;
  using System.IO;
  
  
  public class MyClass {
    
    public static void Main() {
      Console.WriteLine("hello world !");
    }
    
    private void DoSomething() {
    }
  }
}

example output file HelloWorld.vb:

'------------------------------------------------------------------------------
' 
'     This code was generated by a tool.
'     Runtime Version:4.0.30319.18408
'
'     Changes to this file may cause incorrect behavior and will be lost if
'     the code is regenerated.
' 
'------------------------------------------------------------------------------

Option Strict Off
Option Explicit On

Imports System
Imports System.IO

Namespace MyNamespace
  
  Public Class [MyClass]
    
    Public Shared Sub Main()
      Console.WriteLine("hello world !")
    End Sub
    
    Private Sub DoSomething()
    End Sub
  End Class
End Namespace

In the above example I have added an empty method. We will make it more complex now. The method will be called with parameters from Main() and return a value to a local variable. The local variable will be stored in a field via a property.

public static void Test2() {
    CodeCompileUnit lUnit = new CodeCompileUnit();

    CodeNamespace lNamespace = new CodeNamespace("MyNamespace");
    lNamespace.Imports.Add(new CodeNamespaceImport("System"));
    lUnit.Namespaces.Add(lNamespace);

    CodeTypeDeclaration lClass = new CodeTypeDeclaration("MyClass");
    lClass.IsClass = true;
    lClass.Attributes = MemberAttributes.Public;
    lNamespace.Types.Add(lClass);


    // -----------------------------------------------
    // method DoSomething()
    // -----------------------------------------------

    CodeTypeParameter lClassAsParameter = new CodeTypeParameter(lClass.Name);
    CodeTypeReference lClassReference = new CodeTypeReference(lClassAsParameter);
    CodeParameterDeclarationExpression lClassExpression = new CodeParameterDeclarationExpression(lClassReference, "xClass");
    CodeMemberMethod lDoSomething = new CodeMemberMethod();
    lDoSomething.Attributes = MemberAttributes.Public;
    lDoSomething.Comments.Add(new CodeCommentStatement("This is an example comment for our method DoSomething()."));
    lDoSomething.Name = "DoSomething";
    lDoSomething.ReturnType = new CodeTypeReference(typeof(double));
    lDoSomething.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "xInteger"));
    lDoSomething.Parameters.Add(new CodeParameterDeclarationExpression(typeof(string), "xString"));
    lDoSomething.Parameters.Add(lClassExpression);
    lDoSomething.Statements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(1.0)));
    lClass.Members.Add(lDoSomething);


    // -----------------------------------------------
    // private field _MyField
    // -----------------------------------------------

    CodeMemberField lField = new CodeMemberField(typeof(long), "_MyField");
    lField.Attributes = MemberAttributes.Private;
    lField.InitExpression = new CodePrimitiveExpression(10);
    lClass.Members.Add(lField);


    // -----------------------------------------------
    // property MyProperty
    // -----------------------------------------------

    CodeMemberProperty lProperty = new CodeMemberProperty();
    lProperty.Name = "MyProperty";
    lProperty.Attributes = MemberAttributes.Public;
    lProperty.Type = new CodeTypeReference(typeof(long));
    lProperty.GetStatements.Add(new CodeMethodReturnStatement(new CodePrimitiveExpression(359)));
    lProperty.SetStatements.Add(new CodeAssignStatement(new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), lField.Name), new CodePropertySetValueReferenceExpression()));
    lClass.Members.Add(lProperty);


    // -----------------------------------------------
    // Main()
    // -----------------------------------------------

    CodeEntryPointMethod lMain = new CodeEntryPointMethod();
    lClass.Members.Add(lMain);

    // local double variable d
    CodeVariableReferenceExpression lLocalVariable_d = new CodeVariableReferenceExpression("d");
    CodeVariableDeclarationStatement lLocalVariableStatement_d = new CodeVariableDeclarationStatement(typeof(double), lLocalVariable_d.VariableName);
    lMain.Statements.Add(lLocalVariableStatement_d);

    // local integer variable i
    CodeVariableReferenceExpression lLocalVariable_i = new CodeVariableReferenceExpression("i");
    CodeVariableDeclarationStatement lLocalVariableStatement_i = new CodeVariableDeclarationStatement(typeof(int), lLocalVariable_i.VariableName);
    lLocalVariableStatement_i.InitExpression = new CodePrimitiveExpression(0);
    lMain.Statements.Add(lLocalVariableStatement_i);

    // local class variable MyClass
    CodeVariableReferenceExpression lLocalVariable_Class = new CodeVariableReferenceExpression("lClass");
    CodeVariableDeclarationStatement lLocalVariableStatement_Class = new CodeVariableDeclarationStatement(lClassReference, lLocalVariable_Class.VariableName);
    lLocalVariableStatement_Class.InitExpression = new CodeObjectCreateExpression(lClass.Name, new CodeExpression[] { });
    lMain.Statements.Add(lLocalVariableStatement_Class);

    // DoSomething() method call
    CodeMethodInvokeExpression lDoSomethingExpression = new CodeMethodInvokeExpression(lLocalVariable_Class, lDoSomething.Name, new CodeExpression[] { lLocalVariable_i, new CodePrimitiveExpression("hello"), lLocalVariable_Class});
    CodeAssignStatement lAssignment = new CodeAssignStatement(lLocalVariable_d, lDoSomethingExpression);
    lMain.Statements.Add(lAssignment);
    //lMain.Statements.Add(lDoSomethingExpression); // without assignment

    // cast the "double" result to type "long" and write it to field _MyField via property MyProperty
    CodePropertyReferenceExpression lPropertyExpression = new CodePropertyReferenceExpression(lLocalVariable_Class, lProperty.Name);
    CodeCastExpression lCastExpression = new CodeCastExpression(typeof(long), lLocalVariable_d);
    lAssignment = new CodeAssignStatement(lPropertyExpression, lCastExpression);
    lMain.Statements.Add(lAssignment);

    // -----------------------------------------------
    // create source code
    // -----------------------------------------------

    string lDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\";
    CodeGeneratorOptions lOptions = new CodeGeneratorOptions();
    lOptions.IndentString = "  "; // or "\t";
    lOptions.BlankLinesBetweenMembers = true;

    // generate a C# source code file
    CSharpCodeProvider lCSharpCodeProvider = new CSharpCodeProvider();
    using (StreamWriter lStreamWriter = new StreamWriter(lDesktopPath + "MoreComplex.cs", false)) {
        lCSharpCodeProvider.GenerateCodeFromCompileUnit(lUnit, lStreamWriter, lOptions);
    }
} //

example output:

//------------------------------------------------------------------------------
// 
//     This code was generated by a tool.
//     Runtime Version:4.0.30319.18408
//
//     Changes to this file may cause incorrect behavior and will be lost if
//     the code is regenerated.
// 
//------------------------------------------------------------------------------

namespace MyNamespace {
  using System;
  
  
  public class MyClass {
    
    private long _MyField = 10;
    
    public virtual long MyProperty {
      get {
        return 359;
      }
      set {
        this._MyField = value;
      }
    }
    
    // This is an example comment for our method DoSomething().
    public virtual double DoSomething(int xInteger, string xString, MyClass xClass) {
      return 1D;
    }
    
    public static void Main() {
      double d;
      int i = 0;
      MyClass lClass = new MyClass();
      d = lClass.DoSomething(i, "hello", lClass);
      lClass.MyProperty = ((long)(d));
    }
  }
}

Is your head burning already? This was quite complex. As usual there are easier ways for lazy people. I do not recommend any shortcuts. It undermines the idea of flexibility.

public static void Test3() {
    CodeCompileUnit lUnit = new CodeCompileUnit();

    CodeNamespace lNamespace = new CodeNamespace("MyNamespace");
    lNamespace.Imports.Add(new CodeNamespaceImport("System"));
    lUnit.Namespaces.Add(lNamespace);

    CodeTypeDeclaration lClass = new CodeTypeDeclaration("MyClass");
    lNamespace.Types.Add(lClass);

    // write Main entry point method
    CodeEntryPointMethod lMain = new CodeEntryPointMethod();
    lMain.Statements.Add(new CodeSnippetExpression("Console.WriteLine(\"hello world !\")"));
    lClass.Members.Add(lMain);

    string lDesktopPath = Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory) + @"\";
    CodeGeneratorOptions lOptions = new CodeGeneratorOptions();
    lOptions.IndentString = "  "; // or "\t";
    lOptions.BlankLinesBetweenMembers = true;

    // generate a C# source code file
    CSharpCodeProvider lCSharpCodeProvider = new CSharpCodeProvider();
    using (StreamWriter lStreamWriter = new StreamWriter(lDesktopPath + "HelloWorldForLazyPeople.cs", false)) {
        lCSharpCodeProvider.GenerateCodeFromCompileUnit(lUnit, lStreamWriter, lOptions);
    }
} //

We created source code in the runtime environment. How can we execute it?
The next example compiles a class into an assembly and then executes the Main() method, which is automatically defined as the entry point. This happens in memory. If you want to write the executable code to a disk, then set GenerateInMemory to false and define a proper OutputAssembly path in the compiler parameters (variable lParameters). Use CompileAssemblyFromFile() instead of CompileAssemblyFromSource(). Btw. CompileAssemblyFromDom() would accept CodeCompileUnits (eg. used in Test2) as input data. Therefore you don’t have to generate a source code file to compile your code structure.

private static string[] _MyCode = new string[] { 
    "using System;" +
    "public class MyClass {"  +
    "public static void Main() { Console.WriteLine(\"hello world !\"); }" +
    "}" };


public static void Test4() {
    CSharpCodeProvider lCodeProvider= new CSharpCodeProvider();
    CompilerParameters lParameters = new CompilerParameters();
    //lParameters.ReferencedAssemblies.Add("System.dll");
    lParameters.GenerateInMemory = true;
    lParameters.GenerateExecutable = true;
    lParameters.OutputAssembly = "HelloWorld";

    CompilerResults lCompilerResults = lCodeProvider.CompileAssemblyFromSource(lParameters, _MyCode);

    if (lCompilerResults.Errors.Count > 0) {
        foreach (CompilerError lError in lCompilerResults.Errors) Console.WriteLine(lError.ToString());
    }
    else {
        Console.WriteLine("Compiled succesfully " + lCompilerResults.PathToAssembly);
        Console.WriteLine("Executing code now");
        MethodInfo m = lCompilerResults.CompiledAssembly.EntryPoint;
        m.Invoke(null, new object[] {});

    }
    Console.ReadLine();
} //

example output:
Compiled succesfully
Executing code now
hello world !

Expression Trees

Lambda expressions are using expression trees. The data-structure is like a tree. We are not necessarily talking about code here. Lambda expressions are not source code in the classical sense, because compilers translate expressions into code. In fact you don’t know the result, all you need to do is describing the code in an expression tree. For instance LINQ can interact between your code and a database. It can generate SQL queries. And these have nothing to do with the C# source code.

Let’s use an expression tree to generate another “Hello World” example at runtime. For this we need to implement the System.Linq.Expressions namespace. This is not really a part of reflection. I touch on the topic here to have it mentioned before we continue with Emit, which is far more on spot.

public static void Test5() {
    Expression A = Expression.Call(null, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(String) }), Expression.Constant("hello world !"));
    Expression B = Expression.Call(null, typeof(Console).GetMethod("ReadLine", new Type[] { }), null);

    Expression[] Expressions = new Expression[] { A, B };
    BlockExpression lBlockExpression = Expression.Block(Expressions);

    Action lAction = Expression.Lambda<Action>(lBlockExpression).Compile();
    lAction();
} //

Let’s build a simple calculator now. Imagine someone enters a mathematical formula in a TextBox and wants to calculate it. I have seen so many solutions on the internet and I can tell you for sure they are all far too long! In the following code you just need to add some “nice features” like pre-parsing to allow more user flexibility. The entire Math library is yours! May the 4th be with you 😉

public static void Test6() {
    string lTextBoxText = "Math.Floor(5.0  * (3.0 + 7.0) / 9.0 * Math.Exp(3.0))";
    string[] lCode = new string[] { 
        "using System;" +
        "public class MyClass {"  +
        "public static double Calc() { return (double)" + lTextBoxText + "; }" +
        "}" };


    CSharpCodeProvider lCodeProvider = new CSharpCodeProvider();
    CompilerParameters lParameters = new CompilerParameters();
    lParameters.GenerateInMemory = true;
    lParameters.GenerateExecutable = false;
    lParameters.OutputAssembly = "CalcAssembly";

    CompilerResults lCompilerResults = lCodeProvider.CompileAssemblyFromSource(lParameters, lCode);

    MethodInfo m = lCompilerResults.CompiledAssembly.GetType("MyClass").GetMethod("Calc");
    double d = (double)m.Invoke(null, null);
    Console.WriteLine("calculation result is " + d);
    Console.WriteLine("cross check result is " + (Math.Floor(5.0 * (3.0 + 7.0) / 9.0 * Math.Exp(3.0))));

    Console.ReadLine();
} //

example output:
calculation result is 111
cross check result is 111

Do you remember the post about extension methods? Unfortunately we cannot write any extension method for static classes like the .Net framework Math class. So I am going to use the string class instead. The calculator looks a little bit nicer then.

public static class MathExtension {
    public static double Formula(this string xFormula) {
        string[] lCode = new string[] { 
            "using System;" +
            "public class MyClass {"  +
            "public static double Calc() { return (double)" + xFormula + "; }" +
            "}" };


        CSharpCodeProvider lCodeProvider = new CSharpCodeProvider();
        CompilerParameters lParameters = new CompilerParameters();
        lParameters.GenerateInMemory = true;
        lParameters.GenerateExecutable = false;
        lParameters.OutputAssembly = "CalcAssembly";

        CompilerResults lCompilerResults = lCodeProvider.CompileAssemblyFromSource(lParameters, lCode);

        MethodInfo m = lCompilerResults.CompiledAssembly.GetType("MyClass").GetMethod("Calc");
        return (double)m.Invoke(null, null);
    } //        

} //

// how to call the extension method
public static void Test7() {
    string lTextBoxText = "Math.Floor(5.0  * (3.0 + 7.0) / 9.0 * Math.Exp(3.0))";
    double d = lTextBoxText.Formula();
    Console.WriteLine(d);
    Console.ReadLine();
} //

Epilogue

There are some stock market trading applications, which allow users to add their own algorithmic trading strategies. Wouldn’t it be great to enter your code in C# and use the .Net framework instead of reinventing the wheel and come up with your own scripting language that will never reach any widely recognized state of the art?