Monday, December 12, 2011

Real World Example : Simple Publish/Subscribe Pattern with Reactive Extensions

Shown below is a requirement.

Let me explain a little about what I want to achieve. I have an entity called “Frequent” which implements INotifyPropertyChanged interface. So I can subscribe to the change notification and then upon firing the event, I simply increment a counter. Now, my requirement is that the PropertyChanged can fire way too quickly as simulated in the for-loop. So in UI applications, it doesn’t make sense for me to fire property changed events that frequently as in a real world intensive WPF application, this can become your biggest bottleneck (among several others things).

So my requirement is that, within 1 second, I would like to receive only 1 change notification per property, if it has changed indeed. The simple implementation for this would be to do something like pushing the properties that have changed into a queue and process the queue once a second and then raise change notification event. This can be done very easily but then it can be a little tedious job for such a requirement to restrict an event from firing more than X times a second.

So I was looking at the Reactive Extensions (Rx Framework) and it occurred to me that it should support Observer pattern out of the box. So I started playing with it but hit a road block immediately. There are numerous resources that shows how to generate observables from Timers, Time Intervals, Enumerables, etc but what I want to is to take advantage of extension methods supported by Rx Framework on IObserver such as Throttle(), Buffer(), Window(), etc on a simple Pub-Sub system. May be I did not look hard enough but I could not find a simple example. So I thought it would be helpful for rest of the people like me if I made a blog post.

In my implementation, the Frequent object is by itself a Publisher and a Subscriber. In Rx terms – IObservable and IObserver. Instead of implementing these interfaces, I want to have some observable of strings where I will publish a property that has changed and the subscriber on the observable would receive it. So for that purpose of simple message passing between Observers and Observables, you can use a Subject<T>. There are other variants like ReplaySubject<T>, BehaviorSubject<T>, AsyncSubject<T>, etc. but that is out of scope of this post. I publish on Subject<T> and then the subscribers who subscribed earlier to it would be notified of these messages.

Shown below is a the Frequent class implementation.

Take a minute or two to go through the simple class, it is self explanatory. All I am doing is that when a property changes, instead of firing it immediately, I simply notify my throttler about the property that has changed. The throttler’s responsibility is to determine when to notify the subscribers about this change. Shown below is the implementation.

You can read my comments that I wrote out of frustrations. All I do in this simple façade is to wrap an Observable –> Subject<string> and buffer the messages received for 1/2 second and then get unique messages from the buffer and publish it to the subscribers. This is all done in the constructor. The other methods are simply my take on making things simple for the consumer of this class.

Rx is complex and powerful but in my opinion it has a very steep learning curve. But it surely did save a good few days of implementation for my team. Again, I am very new to Rx, so if you have some better ways to do it, then please let me know.

Friday, December 09, 2011

Hannspad Hannspree SN10T2 – Rooting, Android Market and Some Crazy stuff

Recently the Android Tablet bug bit me which led me to buy Hannspad Hannspree SN10T2 from AliExpress.com. The order was made on the day of Thanksgiving and I received the tablet within two weeks. The whole goal was to get a cheap tablet on which I can try installing custom ROM, may be try and develop some applications. But turns out it is not that simple. See the Slatedriod.com forums has custom ROM but for SN10T1 model but not SN10T2 model – which runs on two different processors. So all the cool stuff I read about that people do with SN10T1 is not applicable for SN10T2 – example being booting the tablet in recovery mode. There are not hard volume buttons that lets me boot into recovery console. I tried all different combinations instead of missing Volume + button but the recovery key sequence remains unknown.

Connecting the Hannspad Tablet to Windows 7 x64

Hooking up the USB cable to the Windows 7 machine doesn’t really install the drivers. You can still be able to copy files around once you enable the USB File Transfer on the tablet. If you are new like me, just drag the notifications bar on top of the tablet and the instructions then are clear enough for you to know what to do. So first time you hook up the tablet, you get the message saying OMAP-3/4 driver is not found. Don’t even fight it, there is a really simple way to install the driver for the tablet.

  1. Download Super One Click from Shortfuse.org. The direct link to what I am using is here. It is version 2.3.1.
  2. Extract the zip file to some place you have your portable applications. I put it in temp but now I have a problem deleting the folder because driver was installed from this location??
  3. Launch SuperOneClick.exe and then click on Advanced Tab.
  4. Click on Check Driver.
  5. Then say OK for installation of the driver.
  6. Accept Windows warning about unsigned driver and move on.

What this driver lets you do is to let ADB (Android Debug Bridge or visualize like a remote shell access for your tablet unix system) identify that this device is hooked up and running.

Rooting the SN10T2 (may work for other tablets too!)

If you search for information on how to root the SN10T2, the first thing you see is the article by Sir Shagsalot (Winking smile). It has precisely what you need to do in order to enable Super User access for the programs running on your Android Tablet. Since the information is not so eye-soothing, I will try to replicate the information. But be aware

  1. The information here is from the article I mentioned above plus my experience struggling with the Tablet.
  2. I am not an Android Expert – I am just a software developer who writes software for a living mostly on Windows Platform.
  3. Don’t blame me for any physical or mental or financial pain that may cause as a result of following this information.
  4. Rooting implies the warranty is void. You cannot bitch about your tablet to your vendor anymore. Not my problem again Smile

Option 1 : Using the same SuperOneClick

If you followed the previous steps, you can use SuperOneClick to Root your device.

Option 2 : Using z4Root 

  1. Download the z4root.apk and place it in your SD Card on the tablet.
  2. On the tablet, go to Menu->Settings->Application Settings and check the option for Unknown Sources.
  3. Now go to Home->Applications->ES File Explorer.
  4. Navigate to the z4root.apk wherever you copied it.
  5. Install the APK file.
  6. Then open the z4root application.
  7. You will see two options –> Temporary Root or Permanent Root. If your application is already rooted, you will see the option to Unroot.
  8. I selected Permanent Root.
  9. Then wait until you see “Rebooting..”. If the tablet doesn’t reboot in say 10 minutes, I would not bother to wait. Just restart the tablet manually. It is fine!

The Android SDK Tools

Basically, rooting gives you Super user access and lets you access the shell from ADB console. The super one click application distributes the ADB console application if you poke inside the installation folder.

Anyway for you to officially get the ADB application, you can download the Android SDK from here. 

  1. Download the Android SDK.
  2. Download the Java Development Kit, if you don’t have it already. You need JDK not JRE.
  3. Install JDK. Install Android SDK.
  4. Now in the Android folder (C:\Program Files(x86)\Android\android_sdk\), launch the SDK Manager application. See image below.
  5. You need to check “Android SDK Tools” and then click “Install Packages”.
  6. Once done, you will find a folder called “platform-tools”.

image

Some fun with ADB.

  • Open command prompt and assuming platform-tools is in your PATH.

    (Of course, the table is connected to the machine, USB Debugging enabled on the tablet).

  • Listing all the devices – adb devices
  • Opening the Unix Shell for your tablet – adb shell
  • Copying files from your PC to the device
    • For SD Card, you don’t need to mount as it is already mounted for “Read-Write”. Just run the command -
      • adb push c:\myfiles\superdocument.pdf /sdcard/
    • For copying to /system/app folder, which you may have to do for manual installation of Google Apps and Market
      • Go to the shell of tablet using “adb shell”. Now inside the shell,
      • Mount the /system using the command
        • mount -o remount,rw /dev/block/mmcblk0p5 /system
      • Copy the files you want to push to /system/app, using
        • push c:\files\superapp.apk /system/app/
      • Unmount the /system using the command
        • mount -o remount,ro /dev/block/mmcblk0p5 /system
      • Make sure you unmount once you are done.
  • Reboot the tablet from Windows – adb reboot
  • Copying files from your tablet to the PC – adb pull \sdcard\super.pdf c:\temp\goodbook.pdf

Installing the Android Market on the SN10T2

You can follow the original instructions from top to bottom that Sir ShagsALot wrote here. I will just use the ADB to install the Android Market application.

  • Root your tablet either using SuperOneClick or Z4Root as described previously. Reboot your tablet.
  • Download the required Google Apps distribution from the link mentioned in the article.
  • Extract them to some place on your machine.
  • Make sure ADB is in your PATH. Open the Command Prompt and navigate to the folder where you extracted the googleapps.rar archive.
  • You should see something like shown below.

image

  • Navigate the command prompt into the “app” folder.
  • Using the ADB shell, first mount the /system on your tablet. Then run the following commands to push APK files to /system/root/
    • c:\temp\Working Google Apps\app> adb push GoogleServicesFramework.apk /system/app
    • c:\temp\Working Google Apps\app> adb push OneTimeInitializer.apk /system/app
    • c:\temp\Working Google Apps\app> adb push SetupWizard.apk /system/app
    • c:\temp\Working Google Apps\app> adb push com.android.vending.apk /system/app/Vending.apk
    • Notice the Application for Market is renamed to Vending.apk (don’t think you need to do this, but everyone else uses Vending.apk) Smile
    • Shown below is the command prompt snapshot for your reference

image

  • From the above you should have understand by now that I am only interested in making the Android Market work.
  • Don’t forget to un-mount the /system and also reboot the device as soon as you are done copying.
  • Once the tablet boots, you will be seeing a welcome screen.
  • Just go through the welcome screen and add your google account.
  • Now go to Market and make sure it runs.

Some issues that I had

  • ES File Explorer –> Menu –> Settings –> Root Options. Check the “Root Explorer” failed with message "sorry, test failed. This feature cannot run on your phone” message. So what is the alternative ? Use ADB, it might sound intimidating but it is just a simple Shell prompt. If you are messing around your tablet, most likely you are comfortable with the command prompt.
  • There is a great tool called “File Expert”. It is one tool that impressed me a lot! It is similar to ES File Explorer but much better looking and much easier and intuitive to use. You can upload files from your PC without having to connect your tablet.
    • Install File Expert. You can get it from the App Center that ships with the SN10T2 as well.
    • Launch File Expert. Go to “Share my contents”.
    • Just touch on the “Share via Web” option. Viola!
    • Now you should see a brief message explaining how you can access your tablet SD Card from the Web Browser.
  • Uploading multiple files from File Expert Web UI. You cannot upload more than one file when you are in the root of the SD Card. But create one folder and then you would be able to upload multiple files simultaneously.
  • MOUNT Options in File Expert does not work and can make you believe that it worked. So what is the alternative?? Use ADB.
  • If you manually move some files to /system/app in File Expert of ES File Manager, you may believe it was successfully copied, but they aren’t really done. You don’t see an error that /system has to be mounted.
  • If you are messing with different versions of Google Apps, the one in the link by Sir ShagsALot is the only one I found to be working. If you mess up, then remove the APK files from the /system/app manually.
  • I copied bad APK files and was stuck with Emergency dial screen. So what I realized later was that SetupWizard was badly renamed. So I removed the APK files and copied them keeping the name intact.
  • Again, if you are stuck with wizard screen and reboot doesn’t help, use ADB to delete the APK file.
  • Android Market app is installed but launches and dies immediately. You need to make sure GoogleServicesFramework.apk is properly installed/copied into /system/app folder. When in doubt, repeat the process after taking some break.
  • Android Market App launches but cannot download application. The application page seems to be stuck at “Starting download…”. This only happened when I installed incompatible version of Android App Market.

So these are all the things that I struggled with this week and I hope anyone like me who is new to Android Rooting may find this information helpful. By the way, don’t forget to check out SlateDroid. They are awesome!

Sunday, January 16, 2011

WPF Events to Command redirection using System.Windows.Interactivity

As mentioned previously, I recently used System.Windows.Interactivity library to make a command respond to an event on WPF controls without using any code-behind. In this post, I would give a brief overview and show some code on how to do it. I will try and keep the post to the point and not write anything about hooking up events with code or anything like that. Usual disclaimer applies – I am not entirely familiar with the internals but I know how to make it work and why it works.

So lets start with my simple requirement. I have a text box and as I enter I want to fire a command which processes the text and displays it on a textblock. Of course you can hook up both the controls to the same property in the ViewModel and with .NET 4.0 you can be sure that the getter will fire again when NotifyPropertyChanged is fired. But that is not the point here.

My XAML would simply have a textbox and a textblock. On textbox.TextChanged event fired, I would like to execute a command in my view model. The XAML is shown below.

<UserControl x:Class="Buddi.Training.Advanced.Interactivity.EventToCommandDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Buddi.Training.Infra"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity">
<Grid Background="Beige">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<TextBox Text="{Binding SampleCommandParam,UpdateSourceTrigger=PropertyChanged}" Margin="20">
<i:Interaction.Triggers>
<i:EventTrigger EventName="TextChanged">
<local:EventToCommand Command="{Binding SampleCommand}"
CommandParameter="{Binding SampleCommandParam}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<TextBlock Text="{Binding Message}" Grid.Row="1" Padding="30" FontFamily="Consolas" FontWeight="14"/>
</Grid>
</UserControl>


You need to see how I am hooking up the event to the command in viewmodel which is the DataContext of the View (UserControl to be precise). Lets disect what we have here - We add an event trigger to the TriggersCollection on the Grid using the Interactivity.Triggers attached properties. An event trigger comes with the System.Windows.Interactivity.dll assembly. So add a reference to that library using the "Add Reference" dialog. The Event Trigger then expects an action that can be anything that derives from the TriggerAction<FrameworkElement> class. The TriggerAction derived class should implement one method called "InvokeCommand(object parameter)". The implementation simply takes care of executing the command which are passed to the DependencyProperty we defined in the EventToCommand class. Note that TriggerAction is a DependencyObject, thereby it allows you define Dependency Properties to take full advantage of the Binding, Styles, Animations and what not. So the trigger action is simple - (the following is a special implementation where I handle RoutedCommand different than the others, this is just my scenario and is typically bad - you are programming to the implementation which is not a good idea, but the plan here is to show how you can use the base.AssociatedObject).


namespace Buddi.Training.Infra
{
public class EventToCommand : TriggerAction<FrameworkElement>
{
public ICommand Command
{
get { return (ICommand)GetValue(CommandProperty); }
set { SetValue(CommandProperty, value); }
}

public static readonly DependencyProperty CommandProperty =
DependencyProperty.Register("Command", typeof(ICommand), typeof(EventToCommand), new UIPropertyMetadata(null));




public object CommandParameter
{
get { return (object)GetValue(CommandParameterProperty); }
set { SetValue(CommandParameterProperty, value); }
}

// Using a DependencyProperty as the backing store for CommandParameter. This enables animation, styling, binding, etc...
public static readonly DependencyProperty CommandParameterProperty =
DependencyProperty.Register("CommandParameter", typeof(object), typeof(EventToCommand), new UIPropertyMetadata(null));



protected override void Invoke(object parameter)
{
if (Command == null) return;
if (Command is RoutedCommand)
{
var rc = Command as RoutedCommand;
if (rc.CanExecute(CommandParameter, base.AssociatedObject))
{
rc.Execute(CommandParameter, base.AssociatedObject);
}
}
else
{
if (Command.CanExecute(CommandParameter))
Command.Execute(CommandParameter);
}
}
}
}


That's it! you can now program to the events using the commands that you already have. This lets you keep your code-behind clean and write more testable code than ever. I hope this is useful inspite of it not being the best of the articles. By the way, almost every MVVM framework out there provides an implementation of Event To Command action -eg : Caliburn, Cinch, you name it ... but not always it is possible for us to use a third party framework just for this one reason. In such cases, I thought it is good to know that you can acheive it just by using Microsoft's assembly.

Saturday, January 15, 2011

Working (around) with MSpecs

I just started playing with Machine.Specifications (MSpecs). Overall I am very satisfied with the project but I did ran across some issues - dont get me wrong, it works great but it was more like limitations because I was lame and using Express edition.
My specs are simple - I am trying to create a Dependency Injection Container that does absolutely very little, not as powerful as Unity or any other containers. I dont plan to use it anywhere - just am trying to create one for fun. So the specifications are simple (for now).
 
Mapping Interface to Type, MappingInterfaceToType
  » should allow creating instance of type registered
  
  In case of multiple constructors, pick the one with injection attribute, MultipleConstructorScenario
  » should create instance whose Value property is 20
  
  Container should support singleton instances, SingletonScenario
  » should return the same instance for every invocation
  
  Inner container should be supported, SupportForInnerContainer
  » should return registration from parent and itself


Simple right? Those are the output for my specifications. It it still under works but the output itself explains a lot - thats the power of the MSpecs. Business Analysts write requirements, gives specifications - This can be changed - they give us the requirements and we "program" the specifications. I know it appears to be some rewired Unit Testing, but if unit tests can give me a bunch of specifications and tell me what failed, I would be more than happy to use that.


Now lets write a specification from scratch. Look at the following simple C# code.
 public class Singleton { }
        public class Transient
        {
            public Singleton SingletonInstance { get; private set; }
            public Transient(Singleton ins)
            {
                SingletonInstance = ins;
            }
        }

I would like to register the Singleton class as - singleton and the transient class as - transient. So my specification is, instances of transient whose dependency is a singleton should get the same instance. So that becomes my "Subject"


[Subject("instances of transient whose dependency is a singleton should get the same instance.")]
public class InjectionOfSingletonForTransientResolution
{
}

Now to verify that specification, I need to "establish a context" which is that I need my container to be ready for use.
 Establish context = () =>
 {
            _builder = new TypeBuilder();
 };

Now that context is established, I will just write my specification. I create two instances and both my instances should have the same instance of Singleton.
It Should_Use_The_Same_Instance_when_creating_dependent_Components = () =>
{
            var instance1 = _builder.Resolve();
            var instance2 = _builder.Resolve();
            instance1.ShouldNotEqual(instance2);
            instance1.SingletonInstance.ShouldNotBeNull();
            instance2.SingletonInstance.ShouldNotBeNull();
            instance1.SingletonInstance.ShouldEqual(instance2.SingletonInstance);
};

But you know this would not happen just like that. I have my context and I know what it should do. I need to tell it why it should do that - that specification would pass "because I am registering dependency as singleton and instance as transient". So I add my reasons on why (or when) the specification would pass.
Because I_Am_Making_A_Dependency_Registration_As_Singleton_And_TestSubject_As_Transient = () =>
{
            _builder.Register(new Singleton());
            _builder.Register();
};

The whole specification would look like shown below.
[Subject("instances of transient whose dependency is a singleton should get the same instance.")]
    public class InjectionOfSingletonForTransientResolution
    {
        static ITypeBuilder _builder;

        public class Singleton { }
        public class Transient
        {
            public Singleton SingletonInstance { get; private set; }
            public Transient(Singleton ins)
            {
                SingletonInstance = ins;
            }
        }

        Establish context = () =>
        {
            _builder = new TypeBuilder();
        };

        Because I_Am_Making_A_Dependency_Registration_As_Singleton_And_TestSubject_As_Transient = 
        () =>
        {
            _builder.Register(new Singleton());
            _builder.Register();
        };

        It Should_Use_The_Same_Instance_when_creating_dependent_Components = () =>
        {
            var instance1 = _builder.Resolve();
            var instance2 = _builder.Resolve();
            instance1.ShouldNotEqual(instance2);
            instance1.SingletonInstance.ShouldNotBeNull();
            instance2.SingletonInstance.ShouldNotBeNull();
            instance1.SingletonInstance.ShouldEqual(instance2.SingletonInstance);
        };
    }

When I first run this my specification failed because my container does not handle that yet.
 instances of transient whose dependency is a singleton should get the same instance., InjectionOfSingletonForTransientResolution
  » Should Use The Same Instance when creating dependent Components (FAIL)
  Machine.Specifications.SpecificationException: Should be [not null] but is [null]
     at Machine.Specifications.ShouldExtensionMethods.ShouldNotBeNull(Object anObject) in d:\BuildAgent-03\work\38fe83de684fd902\Source\Machine.Specifications\ExtensionMethods.cs:line 181
     at Analytics.Specifications.Container.InjectionOfSingletonForTransientResolution.<.ctor>b__2() in C:\Users\bhargav\documents\visual studio 2010\Projects\Analytics\Analytics.Specifications\Container\TypeBuilderSpecs.cs:line 159
     at Machine.Specifications.Model.Specification.InvokeSpecificationField() in d:\BuildAgent-03\work\38fe83de684fd902\Source\Machine.Specifications\Model\Specification.cs:line 75
     at Machine.Specifications.Model.Specification.Verify() in d:\BuildAgent-03\work\38fe83de684fd902\Source\Machine.Specifications\Model\Specification.cs:line 53

I fix my container and now I see my specification pass.

One thing to remember is what ever you are working off - your context - it should be static - otherwise the compilation would fail. when looking at others examples, I had a similar question - so here I am telling you upfront.

Running specifications without leaving Visual Studio - No test runners are required.


All my specifications are in a separate class library. I would like to run the specifications without leaving Visual Studio (btw, I am using Express). I remember once upon a time I could make a class library as a startup project and somehow linked NUnit gui runner with the project. I could not get it done with VC# 2010 Express anymore. May be I am missing something. Anyway the solution was to add the following Post-Build event

image

Once my specifications project it built successfully, it automatically generates a nice output. You can use all command line arguments that mspec supports, for now I only care if they pass or fail, hence the simple one.

Debugging my specifications. It was painful


I tried all different strategies like using System.Diagnostics.Debugger.Break() and what not. ConsoleRunner that comes with mspec (mspec.exe) was crashing complaining that it encountered an user defined breakpoint in the code - yeah that was my intention. Anyway to work around that, I create a console program and in the console application, I added reference to my specifications library and from the Git Hub source code for the mspec.exe (thanks to OSS) the following C# code helped me overcome my limitation of not being able to use R# or TestDriven.Net.
 class ContainerSpecsRunner
    {
        static void Main(string[] args)
        {
            //Console.WriteLine(typeof(ITest).Assembly.Location);
            Program prog = new Program(new DefaultConsole());
            prog.Run(new[] { typeof(ITest).Assembly.Location });
        }
    }

ITest is a type that was defined in my specifications assembly. That way I need not worry about any arguments or hardcode path of my assembly. By the way, at work you might be killed for doing this, I am just doing it at my personal projects.

Some samples?


Ok the biggest problem I had was that I could not find some real world examples, the GIT HUB structure of the project was confusing as hell. I was hoping to find some examples, but I could not. As much as I like the project, I hate to see so little or almost non-existent guidance for new users. So here are some of my specifications. These are written by me - I am just learning the style of specs so forgive me if they are not what you wanted them to be. I am just trying to help.
public interface ITest{
    }

    public class Test: ITest{
        [Injector]
        public Test()
        {

        }
    }

    [Subject("Mapping Interface to Type")]
    public class MappingInterfaceToType
    {
        static ITypeBuilder _builder;

        Establish context = () =>
        {
            _builder = new TypeBuilder();
        };

        Because of = () =>
        {
            _builder.Register();
        };

        It should_allow_creating_instance_of_type_registered = () =>
        {
            var resolvedObject = _builder.Resolve();
            resolvedObject.ShouldNotBeNull();
            typeof(Test).ShouldEqual(resolvedObject.GetType()); 
        };
    }

    [Subject("In case of multiple constructors, pick the one with injection attribute")]
    public class MultipleConstructorScenario
    {
        public class Test2 : ITest
        {
            public int Value { get; private set; }
            public Test2(ITest demo)
            {
                Value = 10;
            }

            [Injector]
            public Test2()
            {
                Value = 20;
            }
        }

        static ITypeBuilder _builder;
        Establish context = () => {
            _builder = new TypeBuilder();
        };

        Because of = () =>
        {
            _builder.Register();
        };

        It should_create_instance_whose_Value_property_is_20 = ()=>
{
            var instance = _builder.Resolve();
            instance.ShouldBeOfType();
            (instance as Test2).Value.ShouldEqual(20);
        };
    }

    [Subject("Container should support singleton instances")]
    public class SingletonScenario
    {
        static ITypeBuilder _builder;

        Establish context = () =>
        {
            _builder = new TypeBuilder();
        };

        Because instance_Is_Registered = () =>
        {
            _builder.Register(()=>new Test());
        };

        It should_return_the_same_instance_for_every_invocation = () =>
        {
            _builder.Resolve().ShouldEqual(_builder.Resolve());
        };
    }

    [Subject("Inner container should be supported")]
    public class SupportForInnerContainer
    {
        static ITypeBuilder _builder;
        static ITypeBuilder _child;
        Establish context = () =>
        {
            _builder = new TypeBuilder();
            _child = _builder.CreateChildBuilder();
        };

        Because instance_is_registered_with_child_container = () =>
        {
            _builder.Register(new int[] { 0, 1, 2 });
            _child.Register();
        };

        It should_return_registration_from_parent_and_itself = () =>
        {
            var arr = (int[])_child.Resolve();
            arr.SequenceEqual(new[] { 0, 1, 2 }).ShouldBeTrue();
            _child.Resolve().ShouldBeOfType();
        };
    }


Would be nice if it can print my "Because" field names


Just like the console runner prints my "It" fields, it would be nicer if my reasons are printed. I will see if i can do that myself to the project and may contribute a little.


I hope the examples are useful. By no means they are perfect but they can get you started. You can see in the example I detailed in the beginning, I had a whole bunch of Should statements = that is plain wrong. Each specification should define one thing - otherwise it would be a big mess. Please look at this great project and I really am in love with MSpec.

Thursday, January 13, 2011

Executing RoutedCommand in Code-Behind

Recently I had this issue where we had a bunch of routed commands but those which were to be bound to an event instead of directly on a Button.Command. Anyway with all the event to command redirection (hint: use System.Windows.Interactivity EventTriggers and TriggerAction<FrameworkElement>), the requirement boiled down to executing a RoutedCommand in code behind.

Consider the command had a base class which looks as shown below.

public abstract class CommandBase
{
public ICommand Command { get; private set; }
public CommandBinding CommandBinding { get; private set; }
public CommandBase()
{
Command = new RoutedCommand();
CommandBinding = new CommandBinding(Command, HandlerExecute, HandlerCanExecute);
}

private void HandlerExecute(object sender, ExecutedRoutedEventArgs args)
{
Execute(args.Parameter);
}

private void HandlerCanExecute(object sender, CanExecuteRoutedEventArgs args)
{
args.CanExecute = CanExecute(args.Parameter);
}

protected abstract void Execute(object parameter);

protected abstract bool CanExecute(object parameter);

public static void DoCommandBind(CommandBase command, FrameworkElement element)
{
element.CommandBindings.Add(command.CommandBinding);
}
}

The base class simply provides everything that you need to make use of RoutedCommand. It wraps the command and its command binding whose execute and can execute handlers are redirected to the abstract methods. So the implementation would be as simple as the one shown below and you would have a full fledged RoutedCommand




public class SampleCommand : CommandBase
{
protected override void Execute(object parameter)
{
MessageBox.Show(parameter.ToString());
}

protected override bool CanExecute(object parameter)
{
return parameter != null;
}
}

In the above command, I simply execute the command if there is a parameter sent and when executed display the parameter passed in a MessageBox. In order to use this command in XAML, the markup would be as simple as :



<Button Command="{Binding Sample.Command}" CommandParameter="This is from XAML" Content="From XAML" />

But for the RoutedCommand to work, the CommandBinding associated with it should be added to one of the elements up in the Visual Tree. So one of the parents for the Button should have the CommandBinding for the command to be registered with them. This is performed using the CommandBase.DoCommandBind() method. This is required because - the RoutedCommand - even though it implements ICommand interface, the Execute() and CanExecute() methods simply trigger the events that result in the CommandBinding execute the handlers that were specified when the command binding was being created. Read on MSDN for a much better english explanation. If the command binding cannot be found on any of the ancestors, the command would never fire! This is important to understand when we later look at the C# way to execute a RoutedCommand.



For now, look at the code behind. It is simple and what happens in the constructor is self explanatory.




private CommandBase sample = new SampleCommand();

public CommandBase Sample
{
get { return sample; }
}

public CommandDemo()
{
InitializeComponent();
this.DataContext = this;
//do a command binding on this UserControl itself.
CommandBase.DoCommandBind(sample, this);
}


Gotcha 1 : RoutedCommand does not fire!


If this is the case, then make sure the CommandBinding for the RoutedCommand has been registered properly. You can do it in Code-Behind (like CommandBase.DoCommandBind() in my example) or in XAML (loads of examples online for that).



How do I execute a RoutedCommand from code-behind?


Again, same rules apply. The command binding should be available to be found on the ancestors where the command will be fired. If that is the case, then you can do it in the following way.




var rc = (sample.Command as RoutedCommand);
if (rc.CanExecute("This is command parameter", e.OriginalSource as Control))
rc.Execute("This is command parameter", e.OriginalSource as Control);


Executing the ICommand.Execute(parameter) (eg: sample.Command.Execute("parameter")) would work, but if in any case it does not work, use the method above.


Gotcha 2 : RoutedCommand.CanExecute(parameter) does not fire when executing a RoutedCommand from code-behind!


Yes, ICommand.CanExecute() is just an interface method, its the job the command invoker (if done in code-behind, it is you who is the command invoker) to verify if the command can be executed using CanExecute().



Well, thats all for now, I hope this helps some of us who were struggling with one place solution to execute RoutedCommands in code-behind. Hopefully, I will write one more brief article on using System.Windows.Interactivity.Triggers to redirect an event to a command, the MVVM way of executing actions.

Monday, July 19, 2010

Bing! Are you kidding me!

image

Seriously?? If these things happen, Bing! would never be the search engine that I wish it would become.

Friday, July 16, 2010

WPF Datagrid – Load and Performance

This post is not about performance numbers of WPF Datagrid but simply about what you should be aware of in order to make it perform well. I was not motivated enough to use profiler to show realistic numbers but instead used the Stopwatch class wherever applicable. This post does not go into techniques to handle large amounts of data such as Paging or how to implement paging, but focuses on how to make the datagrid work with large data.

Here is the C# class that generates the data I want to load the Datagrid with.

public class DataItem
{
public long Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public long Age { get; set; }
public string City { get; set; }
public string Designation { get; set; }
public string Department { get; set; }
}

public static class DataGenerator
{
private static int _next = 1;
public static IEnumerable GetData(int count)
{
for (var i = 0; i < count; i++)
{
string nextRandomString = NextRandomString(30);
yield return new DataItem
{
Age = rand.Next(100),
City = nextRandomString,
Department = nextRandomString,
Designation = nextRandomString,
FirstName = nextRandomString,
LastName = nextRandomString,
Id = _next++
};
}
}

private static readonly Random rand = new Random();

private static string NextRandomString(int size)
{
var bytes = new byte[size];
rand.NextBytes(bytes);
return Encoding.UTF8.GetString(bytes);
}
}

My ViewModel has been defined as shown below.

 public class MainWindowViewModel : INotifyPropertyChanged
{
private void Notify(string propName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;

private Dispatcher _current;
public MainWindowViewModel()
{
_current = Dispatcher.CurrentDispatcher;
DataSize = 50;
EnableGrid = true;
_data = new ObservableCollection();
}

private int _dataSize;
public int DataSize
{
get { return _dataSize; }
set
{
LoadData(value - _dataSize);
_dataSize = value;
Notify("DataSize");
}
}

private ObservableCollection _data;
public ObservableCollection Data
{
get { return _data; }
set
{
_data = value;
Notify("Data");
}
}

private bool _enableGrid;
public bool EnableGrid
{
get { return _enableGrid; }
set { _enableGrid = value; Notify("EnableGrid"); }
}

private void LoadData(int more)
{
Action act = () =>
{
EnableGrid = false;
if (more > 0)
{
foreach (var item in DataGenerator.GetData(more))
_data.Add(item);
}
else
{
int itemsToRemove = -1 * more;
for (var i = 0; i < itemsToRemove; i++)
_data.RemoveAt(_data.Count - i - 1);
}
EnableGrid = true;
};
//act.BeginInvoke(null, null);
_current.BeginInvoke(act, DispatcherPriority.ApplicationIdle);
}
}

As you can see, as the DataSize is changed, the data would be loaded. Currently I use a slider to change the load size. This is all pretty easy and fun stuff starts in the XAML.


In order to apply this "Data" to my WPF datagrid, I apply this viewmodel instance to the DataContext of my class. See below for the code-behind that I have for my window

 public partial class MainWindow : Window
{
private MainWindowViewModel vm;

public MainWindow()
{
InitializeComponent();
vm = new MainWindowViewModel();
this.Loaded += (s, e) => DataContext = vm;
}
}

Lets start with the following XAML.


<stackpanel>
<slider maximum="100" minimum="50" value="{Binding DataSize}" />
<label grid.row="1" content="{Binding DataSize}">
<datagrid grid.row="2" isenabled="{Binding EnableGrid}" itemssource="{Binding Data}">
</datagrid>
</stackpanel>

Now build the application and run. The result appear as shown below.


image


As you can see above, I loaded 100 items yet I do not see the scrollbar. Lets change the slider’s Maximum property from 100 to 1000 and rerun the application. Dragging the slider to 1000 at once. So even for the 1000 items, the grid does not respond that well.


image


Let us look at the memory usage.


image


This is pretty heavy for an application with just 1000 items of data loaded. So what is using all this memory? You can hook up a Memory Profiler or use Windbg to look at the memory content but since I already know what is causing this issue, I am not going through that.


This issue is that the DataGrid has been placed inside a StackPanel. When vertically stacked, the StackPanel basically gives its children all the space that they ask for. This makes the DataGrid create 1000 rows (all the UI elements needed for each column of each row !!) and render it. The virtualization of the DataGrid did not come into play here.


So let us make a simple change and put the DataGrid inside a grid. The XAML for which is shown below.

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Slider Value="{Binding DataSize}" Minimum="50" Maximum="1000"/>
<Label Content="{Binding DataSize}" Grid.Row="1"/>
<DataGrid ItemsSource="{Binding Data}" Grid.Row="2" IsEnabled="{Binding EnableGrid}">
</DataGrid>
</Grid>

When I run the application, you would notice that as I load 1000 items, the performance of the same application (no code changes, except that XAML one I just talked about) is a lot better than what it was. Moreover I see nice scrollbars.


image

Let us look at the memory usage.


image


Wow! 10 folds difference. This until now appears to be a re-talk about my previous post on WPF Virtualization. The same rules applies to DataGrid as well. Read this post if you are intertested.


So what else am I talking here.



  • If you notice the ViewModel code, you should be seeing that I disable the grid as I load data and enable it back once I am done. I have not really tested to see if this technique helps, but I did use this technique in HTML pages where loads of items in a listbox were all to be selected and this technique was very useful.
  • In all the screenshots I showed, the grid is sorted. So as the data changes, the grid has to keep sorting the data and show based on what you chose to sort. This, I believe, is a big overhead. Consider removing sort of the datagrid before you change the data if it is a viable option and does not impact the end user. Have not tested this, but the same should apply to the groupings as well (which most of the time cannot be simply removed).

With a simple point of loading the DataGrid into any other panel like Grid, instead of a StackPanel you get to see a lot of difference. The WPF datagrid performs just fine, as long as you keep the viewable region of the grid small.


Shown below is my grid with almost 1 Million data items loaded. The footprint is pretty small compared to the amount of data loaded. This means – either WPF Controls are memory intensive or WPF UI Virtualization is a boon.


Impact of sorting on the DataGrid



  • With no sorting applied on the datagrid, it took almost 20 seconds to load 1 Million items into my collection.
  • With sorting enabled, loading half those items iteself took over 2 minutes and the complete items took over 5 minutes and I killed the application because it was a pain. This matters because the application keeps the CPU busy with all the sort that has to keep happening as your data changes. So for every item added, the sort might be triggered, since I am placing it directly into an observable collection.
  • Instead consider sorting on the backend and not using the datagrid.

image


I can still scroll the application if the virtualization was properly utilized, inspite of the grid binding to 1 million items.


USING BeginInit() and EndInit() on the datagrid.


I changed the ViewModel’s LoadData() such that it calls BeginInit() as it starts loading the data and EndInit() when it done loading the data. This has helped quite a lot. Loading 1 Million items (without any sort applied on the grid) only took around 8 seconds (compared to the 18 seconds it took earlier). Unfortunately I did not spend enough time to use a profiler to show real numbers.


The changed code-behind for the Window is as shown.

public partial class MainWindow : Window
{
private MainWindowViewModel vm;

public MainWindow()
{
InitializeComponent();
vm = new MainWindowViewModel();
this.Loaded += (s, e) => DataContext = vm;
vm.DataChangeStarted += () => dg.BeginInit();
vm.DataChangeCompleted += () => dg.EndInit();
}
}

I also had to include the DataChangeStarted and DataChangeCompleted actions to the Viewmodel class. The changed portion of the ViewModel class is shown below.

	public event Action DataChangeStarted ;
public event Action DataChangeCompleted;

private void LoadData(int more)
{
Action act = () =>
{
//Before the data starts change, call the method.
if (DataChangeStarted != null) DataChangeStarted();
var sw = Stopwatch.StartNew();
EnableGrid = false;
if (more > 0)
{
foreach (var item in DataGenerator.GetData(more))
_data.Add(item);
}
else
{
int itemsToRemove = -1 * more;
for (var i = 0; i < itemsToRemove; i++)
_data.RemoveAt(_data.Count - i - 1);
}
EnableGrid = true;
sw.Stop();
Debug.WriteLine(sw.ElapsedMilliseconds);
if (DataChangeCompleted != null) DataChangeCompleted();
};
//act.BeginInvoke(null, null);
_current.BeginInvoke(act, DispatcherPriority.ApplicationIdle);
}

You can try this out and notice the performance difference yourself.


If the sorting is applied on the datagrid, the performance still hurts in spite of using the above mentioned trick. The overhead of sorting out weighs the performance gain we get calling the BeginInit and EndInit. May be having 1 million records is not realistic enough.

Thursday, July 15, 2010

Using LINQ Aggregate to solve the previous problem

In the previous post I talked about the problem which I simply re-iterate here. From the data which can look like


Name, Value


Sridhar, 1


Ashish,2


PRasanth,3


Ashish,5


Sridhar,6


Prasanth,34


.....

I want to aggregate the values for the names. Look at the previous post for some information on other approaches to solve this simple problem.

The LINQ way to do this would be :


[Test]
public void BTest()
{
var nvcs = tl.GroupBy(s => s.Name)
.Select(s => new NameValueCollection
{
{"Name", s.Key},
{"DrawerId", s.Aggregate(new StringBuilder(),
(seed, g) => seed.AppendFormat("{0};",g.DrawerId)).ToString()}
});
//foreach (var nvc in nvcs)
// Console.WriteLine(nvc["Name"] + " : " + nvc["DrawerId"]);
Assert.AreEqual(4, nvcs.Count());
}


Note that I wanted am generating a list of NameValueCollection and this is not of significance here. If you compare it with the previous implementation that uses dictionary or lists to generate, this solution appears more concise and to those who already knows LINQ should find this really simple.


  • All I would like to take away from this post is that the IEnumerable.Aggregate() method is a great method that is not often mentioned around. We often accumulate some value over a collection of items and aggregate method lets you do just that without all the extra for and seeds that you should track.

Algorithms, performance and getting burnt

After a long time, I am writing something on my blog. So here it is ..

This post is about me starting to solve a small but interesting problem with different approaches and ended up breaking my head against why an algorithm with supposedly O(n) complexity is 4 times slower than O(n^2).

So here's the issue. I have the following data :

Name,Value


Sridhar,1


Ashish,2


Prasanth,3


Sridhar,4


Ashish,5


Sridhar,8

and so on .. I hope you get the idea.

Now what I would like to do is to print the following output.


Sridhar : 1;4;8;....


Ashish : 2;4;.....


Prasanth: 3;......



Note that here, it does not matter what the values are, I am giving this data just for the example. So shown below is my setup which would be used by my implementations. (I am demoing it as a test).



private Stopwatch sw;
[SetUp]
public void SetUp()
{
GC.GetTotalMemory(true); // I dont know why i did this!
tl = new List(10000);
var names = new[] { "Krishna", "Ashish", "Sridhar", "Prasanth" };
foreach (var name in names)
for (var i = 0; i < 2500; i++)
tl.Add(new Ud { Name = name, DrawerId = i.ToString() });
tl.OrderBy(s => s.DrawerId);
sw = Stopwatch.StartNew();
}

[TearDown]
public void TearDown()
{
sw.Stop();
Console.WriteLine(sw.ElapsedMilliseconds);
sw = null;
}

public class Ud
{
public string Name { get; set; }
public string DrawerId { get; set; }
}

private List tl;

The above code is self explanatory. I basically create a lot of Ud objects which generate the data that I presented earlier. Shown below is the most straight forward way to do it. It has two for-loops which makes the complexity O(n^2).



[Test]
public void BasicImplementation()
{
var nvcs = new List();
var list = new List();
foreach (var item in tl)
{
if (list.Contains(item.Name)) continue;

string val = string.Empty;

foreach (var item2 in tl)
{
if (item2.Name == item.Name)
val += item2.DrawerId + ";";
}

nvcs.Add(new NameValueCollection { { "Name", item.Name }, { "DrawerId", val } });
list.Add(item.Name);
}
//foreach (var nvc in nvcs)
// Console.WriteLine(nvc["Name"] + " : " + nvc["DrawerId"]);
Assert.AreEqual(4, nvcs.Count);
}

Now I went ahead and added another potential implementation which gives the same result but instead makes use of dictionary to track the strings that we build for each name in the list of objects. So instinctively, it appears that the dictionary method would be way faster than the one mentioned above. Lets look at that code.



[Test]
public void ADictionary()
{
var vals = new Dictionary();
foreach (var item in tl)
{
if (!vals.ContainsKey(item.Name))
vals[item.Name] = item.DrawerId;
else
vals[item.Name] = vals[item.Name] + item.DrawerId + ";";
}
Assert.AreEqual(4, vals.Values.Count);
}

When I ran these two tests, I did not notice any performance gain with the above O(n) implementation and in fact it was three times slower. So why was it slower? Look at the setup, it has GC.GetTotalMemory(true) which forced a full garbage collection and its time was accounted in the time consumed by this dictionary as well since for the second time (when test with dictionary was executing) it had a lot of strings to clean up. So why did I put it in the first place? The answer is "I was not thinking straight". Never ever use GC classes in your code. It is a bad-bad-bad practice.


So I remove this GC call made and rerun the tests again. Yet I do not see any performance gain. WHY?? I took a lot of time trying to diagnose why this is happening and eventually gave up manual inspection. I downloaded the trail version of dotTrace (which is freaking awesome tool) Performance 4.0 and made it profile both the tests. The culprit was the strings. If you look at the code right, we are generate a lot of strings whose "Concat" operation was so time consuming that it dominated the gain that we obtained using O(n) algorithm.


So the lesson here is "Be watchful of the strings that are generated when your code executes, otherwise you would be burned". It does not matter how small the string concatenation may seem but in cases like above it piles up a lot and screws up your clever algorithm. All I did was to change the tests to use stringbuilder instead of Strings.



  • Do not use GC calls in your code, especially those which force GC.
  • Use a profiler to accurately capture performance information of specific methods or your program. Stopwatch, Timers, etc are not good enough and waste of time.
  • Be aware of the impact of string operations. Use StringBuilder wherever possible. Use String.Format() in other simpler cases.

I will continue in the next post with some code that shows you how to approach the problem I initially started with using LINQ and how simple things would appear.

Sunday, July 11, 2010

Issues with SyntaxHighlighter on my blog

I just messed up my blog template and could not get the syntaxhighlighter plugin to work properly. I will be fixing this shortly but in the meantime if the code seems really ugly to you all, I apologize for the inconvenience.

Wednesday, May 05, 2010

WCF Security – the way I wanted to learn

For intranet applications where the users could be authenticated against Active Directory, using WindowsCredentials, setting up security for a WCF service might not be all that difficult. It might not be difficult even to set up a WCF Service hosted by IIS and make it use the ASP.NET Roles/Providers. But what I wanted was to come up with a series of steps that allows me to secure a WCF service for internet-like applications. While it appears that there would have been 1000s of implementations on the subject where the client application provides a UserName/Password login control and then on the authenticated users would be able to work with the service.

To go back a little, this is what I want

-  I have a client application which has a Login Control and the user enters Username and password. Without proper username.password combination, the service communications going forward should not be allowed. Remember Forms Authentication in ASP.NET ?? Something similar to that.

- I do not want to tie my service strongly to the host – meaning I do not want to make use of the ASP.NET Membership Provider models, though it is relatively easy to do so. So I have a console host program that serves as the WCF Service.

- For every call to an OperationContract, I do not want to read the Message Headers or add extra parameters to see the username and password. I don’t want specific logic within each operation that handles this check.

- I want the operations to be limited to those users with some kind of “Roles”. Basically, i have a set of operations that only users of a Role “X” should be able to perform; whereas there are some other operations for users with other roles.

- I don’t want my communication channel to be open and would want to prevent the users to sniff the traffic to see what is going on.

To summarize these requirements,

- I want a secure communication between client and server.
- I want to restrict access to the service unless the client sends in valid username/password.
- I want to restrict access to operations based on the roles of the calling user.
- I don’t want to deal with Windows Authentication at this moment, since I have plans to host my service on the internet in which case WindowsIdentity is not really preferred.

In this post, I would like to show the way I achieved these goals. Note that I am not qualified enough to make strong statements or give strong explanation on how the security works. The intention of this post would be to help assist developers like me who has little knowledge of WCF Security but do understand how Security works in general. I recommend you read MSDN documentation for the classes and terms I throw here and there.

While, the source code is available for download here : http://drop.io/yskic3h , here in this post I simply mention the steps that I used to achieve each of the goals mentioned above.

1. Secure Communication Channel

Used wsHttpBinding as the binding of my choice. The wsHttpBinding by default employs Windows security. We would have to change that to make use of Message security using “UserName” as clientCredentialType. All this is configured as a binding configuration.


<wsHttpBinding>
<binding name="secureBinding">
<!-- the security would be applied at Message level -->
<security mode="Message">
<message clientCredentialType="UserName"/>
</security>
</binding>
</wsHttpBinding>

Now this bindingConfiguration has to be set on the endpoint as shown



<services>
<service name="WcfService.SecureService" behaviorConfiguration="secureBehavior">
<!--
notice the bindingConfiguration, we are applying secureBinding that
was defined in the bindings section.
-->
<endpoint address="secureService"
binding="wsHttpBinding"
bindingConfiguration="secureBinding"
contract="WcfService.ISecureService"/>
<host>
<baseAddresses>
<add baseAddress="http://truebuddi:8080/" />
</baseAddresses>
</host>
<endpoint address="mex" binding="mexHttpBinding" contract="WcfService.ISecureService"/>
</service>
</services>


Now that we know the server is expecting username and password, we want a custom validator which checks this username and password combination against our custom repository of users. To do that, we would have to configure the service behavior this time. So binding ensures credentials are being passed and the service behavior validates them! ;)




<serviceBehaviors>
<behavior name="secureBehavior">
<serviceMetadata httpGetEnabled="true" />
<serviceDebug includeExceptionDetailInFaults="true" />

<serviceCredentials>

<serviceCertificate
findValue="wcfSecureService"
storeLocation="LocalMachine"
storeName="My"
x509FindType="FindBySubjectName" />

<!--
Now in secureBinding (see in bindings section),
we set the Message security to use "UserName"
as ClientCredentialType. So we would like to
use a custom username password validator.
Here we specify that our custom validator should be used.
-->
<userNameAuthentication
userNamePasswordValidationMode="Custom"
customUserNamePasswordValidatorType="WcfService.CustomUserNamePasswordValidator, WcfService" />
</serviceCredentials>


<!--
The Custom Authorization policy is what used to verify the roles.
For a Role specified in the PrincipalPermission attribute,
IsInRole() method in the Principal that was set from the
CustomAuthorizationPolicy.Evaluate would be invoked.
-->
<serviceAuthorization principalPermissionMode='Custom'>
<authorizationPolicies>
<add policyType='WcfService.CustomAuthorizationPolicy, WcfService' />
</authorizationPolicies>
</serviceAuthorization>

</behavior>
</serviceBehaviors>



In the above configuration, using the serviceCredentials\userNameAuthentication element we specify that the userName/password are to be validated using custom validator type.
This is all configured there. While the username and password authenticates the client on the service, I think it does not really do anything to the communication channel.
To make the channel secure, we make use of certificates. In order to do this, the following steps are required to be done on the development machine so that the sample gets working :



  1. Using the makecert application (can run from Visual Studio Command), create and register the command for exchanging. Note that if you follow the MSDN article on creating certificates using makecert, it does not tell you about enabling the certificate such that it is suitable for key exchanging. So the command that worked for me is

    makecert.exe -sr LocalMachine -ss MY -a sha1 -n CN="wcfSecureService" -sky exchange -pe -r wcfSecureService.cer




  2. We specify the same certificate to be used in the service configuration file using the serviceCredentials\serviceCertificate element. See the configuration snippet shown previously. It basically says "find the certificate by subject name where subject name is 'wcfSecureService' in the certificate store on the local machine and the store would be Personal". For all this to work, note that HTTPS base address should be used.


  3. While the first two steps takes care of the certificate on the server, the client should have some knowledge (basically the client should know the public key with which the messages would be encrypted) of the existence of the certificate. we specify that in the endpoint\identity section of the client configuration [see below]. The encodedValue can be obtained by adding service reference from Visual Studio which generates shit load of configuration on the client, just save the encodedValue and revamp your configuration file.





<client>
<endpoint address="http://truebuddi:8080/secureService" binding="wsHttpBinding"
bindingConfiguration="secureWsHttpBinding"
behaviorConfiguration="ignoreCert"
contract="SecurityDemo.ISecureService">
<identity>
<!-- Don't panic this key is wrong ;) for the sake of this post-->
<certificate encodedValue="AwAAAAEAAAAUAAAAee8O3PpkfSCfjaa3mDmkK+HLb4QgAAAAAQAAAAcCAAAwggIDMIIBcKADAgECAhDgA4A6S0Z/j0d3IFg04e9gMAkGBSsOAwIdBQAwGzEZMBcGA1UEAxMQd2NmU2VjdXJlU2VydmljZTAeFw0xMDA1MDUyMzQ4NTZaFw0zOTEyMzEyMzU5NTlaMBsxGTAXBgNVBAMTEHdjZlNlY3VyZVNlcnZpY2UwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALF7OJsZ6AV5yqSSQyne9j+xwdRLDRoVMleYg0vGvB7W7Bk5zBNbSDCbb+spJR3ykayDoZYpykyY8Q7qzvPuUPdHu7SkMVZ9Ng8B8yAq0zrD8sJwnaqTEY4a8mj8Dt86Yr0wK31aF4VSDRZaK+XDyFd5hWU8Eya+bohhixndMYwNAgMBAAGjUDBOMEwGA1UdAQRFMEOAEJRtYMFDVIgPHFrIf0LU5e+hHTAbMRkwFwYDVQQDExB3Y2ZTZWN1cmVTZXJ2aWNlghDgA4A6S0Z/j0d3IFg04e9gMAkGBSsOAwIdBQADgYEApQ+Hy6e4hV5rKRn93IMcEL3tW2tUYcj/oifGbEPRX329s3cc8QH6jYaNN8cgS5RN+6QffrkvupMSUauGsWia20WHTRI8lyb+1gvvX4NpTxZE6+sZkvIu6R/qIsC6V9pbRCHm3HRFnAoMNZmPTr5mJvzwAQZzOdXMFq0OwakJKEw=" />
</identity>
</endpoint>
</client>



You can also look at this link to get the public key in any case.



For testing purposes, you should also add a behaviorConfiguration on the client's endpoint such that certificates are not validated, once you deploy, you can remove this behavior.




<behaviors>
<endpointBehaviors>
<!-- ignore cerificates validation for testing purposes. -->
<behavior name="ignoreCert">
<clientCredentials>
<serviceCertificate>
<authentication certificateValidationMode="None" />
</serviceCertificate>
</clientCredentials>
</behavior>
</endpointBehaviors>
</behaviors>


On the client config, you should also give the same wsHttpBinding with similar behavior but with few other options added. See snippet and compare it with the binding snippet that was shown earlier for the server




<bindings>
<wsHttpBinding>
<binding name="secureWsHttpBinding">
<security mode="Message">
<message clientCredentialType="UserName"
negotiateServiceCredential="true"
establishSecurityContext="true"/>
</security>
</binding>
</wsHttpBinding>
</bindings>


With this the communication channel is secure. You might have some issues with Certificates but you should be able to use the exception messages to bing for answers online in the forums. Only other part that is left on the client end is to make sure that the client proxy used are set with Username and password. Code for the full client is shown below.




SecureServiceClient client = new SecureServiceClient();
client.ClientCredentials.UserName.UserName = "Krishna";
client.ClientCredentials.UserName.Password = "test";
User test = client.Login();
client.SafeOperationByAdmin();


2. UserName and Password Custom Validation


Implement a type that derives from UserNamePasswordValidator class. You would have to reference the System.IdentityModel.dll and if you remember, we set the custom validator in the service behavior on the service configuration file. While the code shown below does not talk to DB, it should still serve as a good example on custom username and password validation. Note that this Validate() method gets called for evevery



public class CustomUserNamePasswordValidator : UserNamePasswordValidator
{
public override void Validate(string userName, string password)
{
Console.WriteLine("Username validation started");
if (userName == "Krishna" && password == "test")
return;
throw new InvalidCredentialException("Invalid credentials passed to the service");
}
}


3. Restriction of Operations using Roles


The operations can be restricted to users of certain roles by applying a PrincipalPermission attribute on the OperationContract [see below]. The current principal would be checked to see if it is in the role specified, otherwise the operation would not allowed to be executed. Now how do we set this Principal to something? To do this, we need a CustomPrincipal which you should derive from IPrincipal. This Principal implementation has IIdentity which can be WindowsIndetity for Windows Authentication and GenericIdentity for other scenarios. Now this CustomPrincipal should be created and applied somewhere right? This is where the IAuthorizationPolicy comes into play, We should have a custom authorization policy whose Evaluate method should take care of fetching the identity and passing it to a newly created custom principal. This custom principal has to be set as the current principal. All the three code snippets : PrincipalPermission attribute on operations, CustomPrincipal and CustomAuthorizationPolicy is shown below.




///
///This authorization policy is set on the service behavior using service authorization element.
public class CustomAuthorizationPolicy : IAuthorizationPolicy
{
public bool Evaluate(EvaluationContext evaluationContext, ref object state)
{
IIdentity client = (IIdentity)(evaluationContext.Properties["Identities"] as IList)[0];
// set the custom principal
evaluationContext.Properties["Principal"] = new CustomPrincipal(client);
return true;
}

private IIdentity GetClientIdentity(EvaluationContext evaluationContext)
{
return null;
}

public System.IdentityModel.Claims.ClaimSet Issuer
{
get { throw new NotImplementedException(); }
}

public string Id
{
get { throw new NotImplementedException(); }
}
}

public class CustomPrincipal : IPrincipal
{
private IIdentity identity;

public CustomPrincipal(IIdentity identity)
{
this.identity = identity;
}

public IIdentity Identity
{
get
{
return identity;
}
}

public bool IsInRole(string role)
{
return true;
}
}

///in the WCF Service implementation
[PrincipalPermission(SecurityAction.Demand, Role = "Admin")]
public void SafeOperationByAdmin()
{
///more code
}


The newly created Authorization Policy should be configured inside the service configuration file in the serviceBehavior\serviceAuthorization as shown below.





<!--
The Custom Authorization policy is what used to verify the roles.
For a Role specified in the PrincipalPermission attribute,
IsInRole() method in the Principal that was set from the
CustomAuthorizationPolicy.Evaluate would be invoked.
-->
<serviceAuthorization principalPermissionMode='Custom'>
<authorizationPolicies>
<add policyType='WcfService.CustomAuthorizationPolicy, WcfService' />
</authorizationPolicies>
</serviceAuthorization>




To summarize, the following are the steps that should be performed to get the security working in WCF. (Message level security).


  1. Create and register a certificate. Configure the service configuration specifying the certificate to use. This is done in the bindingConfiguration and the binding configuration is then applied on the endpoint.
  2. Configure the service to make use of Message level security. Again done on the server configuration.
  3. Configure the client to use encodedValue for its communication which is the public key. This is done in the bindingConfiguration on the client's endpoint. For testing purposes you can make the client not validate the certificates. This is done on the end point behaviors.
  4. Configure the client's binding to make use of Message level security with UserName.
  5. The client's code should specify the username and password. To validate this information, register a custom UserNamePasswordValidator in the serviceBehavior on the server configuration.
  6. For roles, create a custom prinicipal and set it using a Custom Authorization policy. This authorization policy should be registered in the serviceAuthorization of the serviceBehavior in the server configuration file.



      Again the code is available for download at : http://drop.io/yskic3h . Sometime, in the future, I would try to upload the code to codeplex or put it in the Windows Live Skydrive.