The Problem Solver

Tell me and I will forget
Show me and I will remember
Involve me and I will understand
- Confucius -

Google Ads

This Blog

Syndication

Search

Tags

News





  • View Maurice De Beijer's profile on LinkedIn

Community

Email Notifications

Explore

Archives

February 2009 - Posts

Roy Osherove has just released SilverUnit, a unit testing framework for Silverlight code. I haven't tried this yet but it certainly looks really interesting as you can start running your Silverlight unit tests inside of MS Test or NUnit.

And kind cool to hear this is written in VB Smile

You can find more information and download SilverUnit from CodePlex here.

Enjoy!

www.TheProblemSolver.nl
Wiki.WindowsWorkflowFoundation.eu

Posted by Maurice | 6 comment(s)
Filed under: , , ,

When using self created SSL certificates with HTTPS WCF endpoints you might run into certificate validation errors. The best solution of to make sure all your certificates are fully trusted but sometimes that might not be an easy thing. The next best thing is to the the ServicePointManager.ServerCertificateValidationCallback and have add your own function to validate the certificate. This way you can ignore invalid certificates and keep going as if everything is well.

Take care though as this might open up a can of worms in a production environment.

Enjoy!

www.TheProblemSolver.nl
Wiki.WindowsWorkflowFoundation.eu

Posted by Maurice | 5 comment(s)
Filed under: , ,

The Patterns & Practices group at Microsoft have just released Prism version 2. I am pretty exited about this because Prism version 2 supports both WPF and Silverlight. And as it makes extensive use of the Model - View - ViewModel amongst other design patterns it is a great place to learn, even if you don't use it as is.

Check out the main "Composite Application Guidance for WPF and Silverlight" page here. Or read Blaine Wastell about it here.

Enjoy!

Posted by Maurice | 1 comment(s)

The repository pattern is quite a common design pattern when working with databases. And for a good reason as standardizing code on design patterns it makes it easer to read and understand.

The typical repository pattern in .NET

Most of the time the repository pattern looks something like this.

public interface IRepository<T>
{
    IEnumerable<T> All();
    IEnumerable<T> FindAll(Func<T, bool> exp);
}

Note that I am only implementing the loading of data. Normally there would also be methods for saving, deleting and crating new entities but I have left these out for now.

In regular .NET code that is just fine but in Silverlight not quite. The problem here is the fact that the functions return their result. Not uncommon but as most, if not all, IO actions in Silverlight are asynchronous returning something is not the best way. For Silverlight it is better to pass in a delegate as a callback when the action is complete.

So the logical implementation in Silverlight would be more like this where the action is whatever needs to be done when the request finishes.

public interface IRepository<T>
{
    void All(Action<IEnumerable<T>> action);
    void FindAll(Func<T, bool> filter, Action<IEnumerable<T>> action);
}

unfortunately that doesn’t quite work when we use an ADO.NET Data Service and the Entity Framework to get to our data. In that case the filter needs to be of type Expression<Func<T, bool>>. A slight complication but fortunately the calling code never needs to be aware of it. More on how to use an ADO.NET Data Service from Silverlight in this blog post.

 

The Silverlight implementation of the repository pattern

With that change the interface looks like this;

using System;
using System.Collections.Generic;
using System.Linq.Expressions;
 
namespace SilverlightRepository
{
    public interface IRepository<T>
    {
        /// <summary>
        /// Return all customers.
        /// </summary>
        /// <param name="action">What to do with the customers.</param>
        void All(Action<IEnumerable<T>> action);
 
        /// <summary>
        /// Return subset of customers.
        /// </summary>
        /// <param name="filter">The filter criteria.</param>
        /// <param name="action">What to do with the customers.</param>
        void FindAll(Expression<Func<T, bool>> filter, Action<IEnumerable<T>> action);
    }
}

 

Based upon this interface we can create an implementation to load customers. In this case I have already created an ADO.NET Data Service that serves customer data and set a service reference to it so the Customer class is generated.

My CustomerRepository class looks like this:

using System;
using System.Collections.Generic;
using System.Data.Services.Client;
using System.Linq;
using System.Linq.Expressions;
using System.Windows.Browser;
using SilverlightRepository.NorthwindService;
 
namespace SilverlightRepository
{
    public class CustomerRepository: IRepository<Customer>
    {
        /// <summary>
        /// Return all customers.
        /// </summary>
        /// <param name="action">What to do with the customers.</param>
        public void All(Action<IEnumerable<Customer>> action)
        {
            var query = GetBaseQuery();
            DataServiceQuery<Customer> dsQuery = (DataServiceQuery<Customer>)query;
            dsQuery.BeginExecute(ar => action(dsQuery.EndExecute(ar)), null);
        }
 
        /// <summary>
        /// Return subset of customers.
        /// </summary>
        /// <param name="filter">The filter criteria.</param>
        /// <param name="action">What to do with the customers.</param>
        public void FindAll(Expression<Func<Customer, bool>> filter, Action<IEnumerable<Customer>> action)
        {
            var query = GetBaseQuery();
            query = query.Where(filter);
 
            DataServiceQuery<Customer> dsQuery = (DataServiceQuery<Customer>)query;
            dsQuery.BeginExecute(ar => action(dsQuery.EndExecute(ar)), null);
        }
 
        private static IQueryable<Customer> GetBaseQuery()
        {
            Uri uri = new Uri(HtmlPage.Document.DocumentUri, "NorthwindService.svc");
            NorthwindEntities context = new NorthwindEntities(uri);
 
            var query = from cust in context.CustomerSet
                        select cust;
 
            return query;
        }
    }
}

Note that the FindAll() function uses the same basic query as the All() function and just tags on the extra filter clause like this:

public void FindAll(
    Expression<Func<Customer, bool>> filter, 
    Action<IEnumerable<Customer>> action)
{
    var query = GetBaseQuery();
    query = query.Where(filter);
 
    DataServiceQuery<Customer> dsQuery = (DataServiceQuery<Customer>)query;
    dsQuery.BeginExecute(ar => action(dsQuery.EndExecute(ar)), null);
}

Nice and simple, just the way I like it Smile.

 

Using the CustomerRepository from a page

Loading all customers in the page loaded event is easy and done with these lines of code:

CustomerRepository repository = new CustomerRepository();
repository.All(customers => DataContext = customers);

Note that the ListBox is bound to the DataContext to load its items.

Now if we want to filter the code is almost as easy. Loading all customers from the UK is done with the following code:

CustomerRepository repository = new CustomerRepository();
    repository.FindAll(
        customer => customer.Country == "UK",
        customers => DataContext = customers);

The first lambda expression is the filter criteria and the second binds the DataContext for the ListBox. Using Fiddler we can see that when we ask for the UK customers only those customers are returned over the wire so we can be sure all filtering is done on the server.

image

 

Note that the client doesn’t need to know about the filter being of type Expression<Func<T, bool>>. All we need to do is just pass in simple lambda expression and the DataServiceQuery<T> knows how to handle it.

Enjoy!

Posted by Maurice | 7 comment(s)

One thing I occasionally have to do is  change the way a ListBox item behaves. For example the blue highlight effect when the mouse hovers over it.

image

 

Changing the blue mouse over effect to something else, say the item growing slightly isn’t very hard using Blend. However I find the steps a little awkward so this post should help me remember them and I hope it helps someone else as well.

 

Suppose we start with the following very simple Silverlight page

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SilverlightApplication4.Page"
    Width="640" Height="480">
 
    <Grid x:Name="LayoutRoot" Background="White">
        <ListBox Margin="8,8,0,0" VerticalAlignment="Top" Height="116" Width="77" HorizontalAlignment="Left" >
            <ListBoxItem Content="One"/>
            <ListBoxItem Content="Two"/>
            <ListBoxItem Content="Three"/>
        </ListBox>
    </Grid>
</UserControl>

 

The trick to changing the mouse over effect is changing the ListBox style first.

First select The ListBox in the “ Objects and Timeline” windows. Next select “Object/Edit Stype/Edit a Copy” from the menu and create a new style for the ListBox.

image

Next we need to edit the ListBoxItem style by selecting “Object/Edit Other Style/Edit ItemContainerStyle/Edit a Copy”.

image

Now we are at the level of the ListBox items. Now we need to edit the template itself to make the actual changes we want. So select “Object/Edit Control Parts (Template)/Edit Template from the menu.

image

Only when we get to this level do we see the separate states a ListBoxItem can have. Not very easy to find I admit but here it is. So now select the MouseOver state from the ComonStates.

image

Now we see that there is a change to the fillColor Opacity.

Suppose we want to change that and have the element grow with a mouse over effect. The first step is to delete the current effect. So select the Opacity in the “Objects and Timeline” and press delete. Next to make the item grow we are going to change the Scale Transform on the contentPresenter.

image

And when we run the Silverlight application and move the mouse over the two it looks like this:

image

Of course we could have typed the XAML in by hand but as the complete XAML produced by Blend, se below, is rather long I would rather use Blend, even it it is not exactly intuitive if you ask me. At least next time I know where to look for the steps Smile

<UserControl
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Class="SilverlightApplication4.Page"
    Width="640" Height="480" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
 
    <UserControl.Resources>
        <Style x:Key="ListBoxItemStyle1" TargetType="ListBoxItem">
            <Setter Property="Padding" Value="3"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="TabNavigation" Value="Local"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBoxItem">
                        <Grid Background="{TemplateBinding Background}">
                            <vsm:VisualStateManager.VisualStateGroups>
                                <vsm:VisualStateGroup x:Name="CommonStates">
                                    <vsm:VisualState x:Name="Normal"/>
                                    <vsm:VisualState x:Name="MouseOver">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.2"/>
                                            </DoubleAnimationUsingKeyFrames>
                                            <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
                                                <SplineDoubleKeyFrame KeyTime="00:00:00" Value="1.2"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity">
                                                <SplineDoubleKeyFrame KeyTime="0" Value=".55"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name="SelectionStates">
                                    <vsm:VisualState x:Name="Unselected"/>
                                    <vsm:VisualState x:Name="Selected">
                                        <Storyboard>
                                            <DoubleAnimationUsingKeyFrames Storyboard.TargetName="fillColor2" Storyboard.TargetProperty="Opacity">
                                                <SplineDoubleKeyFrame KeyTime="0" Value=".75"/>
                                            </DoubleAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                </vsm:VisualStateGroup>
                                <vsm:VisualStateGroup x:Name="FocusStates">
                                    <vsm:VisualState x:Name="Focused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Visibility">
                                                <DiscreteObjectKeyFrame KeyTime="0">
                                                    <DiscreteObjectKeyFrame.Value>
                                                        <Visibility>Visible</Visibility>
                                                    </DiscreteObjectKeyFrame.Value>
                                                </DiscreteObjectKeyFrame>
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </vsm:VisualState>
                                    <vsm:VisualState x:Name="Unfocused"/>
                                </vsm:VisualStateGroup>
                            </vsm:VisualStateManager.VisualStateGroups>
                            <Rectangle x:Name="fillColor" IsHitTestVisible="False" Opacity="0" Fill="#FFBADDE9" RadiusX="1" RadiusY="1"/>
                            <Rectangle x:Name="fillColor2" IsHitTestVisible="False" Opacity="0" Fill="#FFBADDE9" RadiusX="1" RadiusY="1"/>
                            <ContentPresenter HorizontalAlignment="Left" Margin="{TemplateBinding Padding}" x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" RenderTransformOrigin="0.5,0.5">
                                <ContentPresenter.RenderTransform>
                                    <TransformGroup>
                                        <ScaleTransform/>
                                        <SkewTransform/>
                                        <RotateTransform/>
                                        <TranslateTransform/>
                                    </TransformGroup>
                                </ContentPresenter.RenderTransform>
                            </ContentPresenter>
                            <Rectangle x:Name="FocusVisualElement" Visibility="Collapsed" Stroke="#FF6DBDD1" StrokeThickness="1" RadiusX="1" RadiusY="1"/>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <Style x:Key="ListBoxStyle1" TargetType="ListBox">
            <Setter Property="Padding" Value="1"/>
            <Setter Property="Background" Value="#FFFFFFFF"/>
            <Setter Property="Foreground" Value="#FF000000"/>
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Top"/>
            <Setter Property="IsTabStop" Value="False"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="TabNavigation" Value="Once"/>
            <Setter Property="BorderBrush">
                <Setter.Value>
                    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                        <GradientStop Color="#FFA3AEB9" Offset="0"/>
                        <GradientStop Color="#FF8399A9" Offset="0.375"/>
                        <GradientStop Color="#FF718597" Offset="0.375"/>
                        <GradientStop Color="#FF617584" Offset="1"/>
                    </LinearGradientBrush>
                </Setter.Value>
            </Setter>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="ListBox">
                        <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="2">
                            <ScrollViewer x:Name="ScrollViewer" Background="{TemplateBinding Background}" BorderBrush="Transparent" BorderThickness="0" Padding="{TemplateBinding Padding}">
                                <ItemsPresenter/>
                            </ScrollViewer>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="ItemContainerStyle" Value="{StaticResource ListBoxItemStyle1}"/>
        </Style>
    </UserControl.Resources>
 
    <Grid x:Name="LayoutRoot" Background="White">
        <ListBox Margin="8,8,0,0" Height="116" HorizontalAlignment="Left" Style="{StaticResource ListBoxStyle1}" VerticalAlignment="Top" Width="77" >
            <ListBoxItem Content="One"/>
            <ListBoxItem Content="Two"/>
            <ListBoxItem Content="Three"/>
        </ListBox>
    </Grid>
</UserControl>

 

Enjoy

Posted by Maurice | 8 comment(s)
Filed under: ,

Most applications allow a user to work both with the mouse and with the keyboard. With the mouse that usually means clicking on buttons or, in the case of a web application, on hyperlinks. using mouse gestures is still not all that common though and that is a shame because it is really easy to add to an application and can be a very useful addition of the user.

To demonstrate how easy it is to add mouse gestures to an ASP.NET application I created a small sample to do just that.

To start with I created a real simple ASP.NET page with a label and two buttons. The label contains a number and the clicking either of the buttons will decrease or increase the number. The page looks like this.

image

Enabling gestures is just a few minutes work Smile.

First I downloaded the latest version of jQuery and the jGesture plug-in.

Wiring the whole thins just takes a few lines of code. In this case I decided to use the left and right gesture as they match the direction of the two arrows on the page. The first thing is to add the two JavaScript file to the page. Next when the page loads we can use the jQuery ready() function to hook up the mouse gesture event handler. Inside our handler we check is the gesture was left or right and if that was the case we just trigger the click action of the appropriate button. Sounds complicated but using jQuery just a few lines of code. The complete JavaScript needed looks like this:

$().ready(function() {
    $().gesture(function(gs) {
        var gestureName = gs.getName();
        if (gestureName == "right") {
            $(".BtnRight").click();
        }
        else if (gestureName == "left") {
            $(".BtnLeft").click();
        }
    });
});

With this code in pace all a use has to do is drag the mouse left or right anywhere over the page to increment or decrement the number. And with the default settings it doesn’t even matter which mouse button he uses.

Note that I use the Button CSS classes as selector instead of the button ID. In this case not really needed but un general this approach works much better with ASP.NET because of the name mangling ASP.NET does.

The complete ASP.NET page looks like this:

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="Gestures._Default" %>
 
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
    <script src="Scripts/jquery-1.3.1.js" type="text/javascript"></script>
   1:  
   2:     <script src="Scripts/jgesture-1.0.3.js" type="text/javascript">
   1: </script>
   2:     <script type="text/javascript">
   3: $().ready(function() {
   4:     $().gesture(function(gs) {
   5:         var gestureName = gs.getName();
   6:         if (gestureName == "right") {
   7:             $(".BtnRight").click();
   8:         }
   9:         else if (gestureName == "left") {
  10:             $(".BtnLeft").click();
  11:         }
  12:     });
  13: });
  14:       
</script>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <table width="100%">
            <col width="50%" />
            <col />
            <col width="50%" />
            <tr>
                <td align="center">
                    <asp:ImageButton ID="BtnLeft" 
                        ImageUrl="~/Img/Back.png" 
                        runat="server" 
                        OnClick="BtnLeft_Click"
                        CssClass="BtnLeft" />
                </td>
                <td align="center">
                    <asp:Label ID="LblNumber" 
                        runat="server" 
                        Text="0" 
                        Font-Size="XX-Large"></asp:Label>
                </td>
                <td align="center">
                    <asp:ImageButton ID="BtnRight" 
                        ImageUrl="~/Img/Next.png" 
                        runat="server" 
                        OnClick="BtnRight_Click"
                        CssClass="BtnRight" />
                </td>
            </tr>
        </table>
    </div>
    </form>
</body>
</html>

 

Enjoy!

Downlaod source code

Posted by Maurice | 7 comment(s)
Filed under: ,

I just noticed that a the Visual Studio Autocomplete Documentation version of JQuery 1.3.1 is now available. This makes using jQuery 1.3.1, the latest verion at the moment, al lot easier.

See the jQuery downloads page here: http://docs.jquery.com/Downloading_jQuery or download directly from Google Code here: http://code.google.com/p/jqueryjs/downloads/detail?name=jquery-1.3.1-vsdoc.js

Enjoy!

Posted by Maurice | with no comments
Filed under:

In my previous blog post I demonstrated how you can use Ninject in your Silverlight application to automatically inject dependencies and make live easier. In the sample I injected the dependency, the PingService, inside my PageModel constructor. That worked just fine because the PingService is lightweight and stateless. However suppose creation is much more involved and you don’t need it all the time so you really want to divert creation until you really need the PingService. Well we can by just a few simple changes.

 

Changing the PageModel to defer loading of the PingService

This is actually a very easy change. All we need to do is change to constructor from expecting a PingService to expecting a IKernel. The IKernel is the Ninject main object and Ninject will take care of injecting itself. Kind of cool as the Page, which creates and uses the PageModel , doesn’t even need to be aware of the change, Ninject will do all the work here Smile.

Now we can change the ExecutePing() function to use the kernel to create the PingService when needed and we are done. The new PageModel looks like this:

using System;
using System.ComponentModel;
using System.Threading;
using Ninject.Core;
 
namespace NinjectSample
{
    public class PageModel : INotifyPropertyChanged
    {
        public PageModel(IKernel kernel)
        {
            _kernel = kernel;
            _context = SynchronizationContext.Current;
        }
 
        private IKernel _kernel;
        private SynchronizationContext _context;
        public DateTime TheResult { get; set; }
 
        public void ExecutePing()
        {
            PingService.PingService proxy = _kernel.Get<PingService.PingService>();
            proxy.BeginPing(proxy_PingCompleted, proxy);
        }
 
        void proxy_PingCompleted(IAsyncResult result)
        {
            PingService.PingService proxy = (PingService.PingService)result.AsyncState;
            _context.Post(state =>
                {
                    TheResult = proxy.EndPing(result);
 
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("TheResult"));
                }, null);
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

The normal generated WCF PingService will work just fine as will the Page, no changes there. The only other change we need to make is to the TestPingService as this was a very simple implementation before. Not that it is very complicated now but it needs to work with a dummy IAsyncResult. The complete fake code looks like this:

using System;
 
namespace NinjectSample
{
    public class TestPingService : PingService.PingService
    {
        public IAsyncResult BeginPing(AsyncCallback callback, object asyncState)
        {
            TestAsyncResult result = new TestAsyncResult() { AsyncState = asyncState };
            callback(result);
            return result;
        }
 
        public DateTime EndPing(IAsyncResult result)
        {
            // Birthdate Charles Babbage
            return new DateTime(1791, 12, 26);
        }
    }
 
    class TestAsyncResult : IAsyncResult
    {
        public object AsyncState { get; set; }
        public System.Threading.WaitHandle AsyncWaitHandle { get; set; }
        public bool CompletedSynchronously { get; set; }
        public bool IsCompleted { get; set; }
    }
}

 

Easy right Smile

Conclusion

Even though we are now using lazy loading instead of eager loading Ninject still makes live easy for us.

Enjoy!

Download source code

Posted by Maurice | 6 comment(s)

One useful feature when developing more complex code is using an inversion of control (IOC) container to do dependency injection. The basic principal of inversion of control, or dependency injection, is to pass in any dependencies when an object is created and not create them when needed. This way the code is much more decoupled and much easier to unit test.

Dependency injection with Silverlight

When developing regular .NET code there are plenty of IOC containers to choose from. However when it comes down to Silverlight the choice isn’t quite as big. I am aware of only two IOC containers you can use with Silverlight, Ninject and Unity. In this example I am going to use Ninject but the same approach would be perfectly valid using Unity.

 

The basic application

I am going to use a very basic application to demonstrate using Ninject with Silverlight. Just a TextBlock and Button on the form and when the button is called we are going to call a WCF service and call a ping method returning the current time.

image

The page is real simple. All I do is create a PageModel, make it the DataContext for the form and call the ExecutePing function when the button is clicked.

using System.Windows;
using System.Windows.Controls;
 
namespace NinjectSample
{
    public partial class Page : UserControl
    {
        private PageModel _model;
 
        public Page()
        {
            InitializeComponent();
 
            _model = new PageModel();
            DataContext = _model;
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            _model.ExecutePing();
        }
    }
}

The PageModel class is also very straightforward and looks like this:

using System;
using System.ComponentModel;
using NinjectSample.PingService;
 
namespace NinjectSample
{
    public class PageModel: INotifyPropertyChanged
    {
 
        public DateTime TheResult { get; set; }
 
        public void ExecutePing()
        {
            PingServiceClient proxy = new PingServiceClient();
            proxy.PingCompleted += proxy_PingCompleted;
            proxy.PingAsync();
        }
 
        void proxy_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            TheResult = e.Result;
 
            if (PropertyChanged != null)
                PropertyChanged(this, new PropertyChangedEventArgs("TheResult"));
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

 

So this works but there is a problem. This code is not very testable as it creates the PingServiceClient, which calls the server, while executing. Lets see how we can refactor this using Ninject to create a bit more maintainable and testable code.

Adding Ninject

First make sure you download the Silverlight version of Ninject from the website here. And add a reference to the DLL’s from the Silverlight project.

image

So lets do the minimum work to use Ninject and have it insert the dependency. Instead of using the new operator to create the PageModel we are going to let Ninject handle this using the following code:

IKernel kernel = new StandardKernel();
_model = kernel.Get<PageModel>();

And to have Ninject inject the dependency on the WCF service we are going to change it to receive he proxy object in the constructor like this:

public class PageModel : INotifyPropertyChanged
{
    public PageModel(PingServiceClient proxy)
    {
        _proxy = proxy;
    }
 
    private PingServiceClient _proxy;
    public DateTime TheResult { get; set; }
 
    public void ExecutePing()
    {
        _proxy.PingCompleted += proxy_PingCompleted;
        _proxy.PingAsync();
    }
 
    void proxy_PingCompleted(object sender, PingCompletedEventArgs e)
    {
        _proxy.PingCompleted -= proxy_PingCompleted;
        TheResult = e.Result;
 
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs("TheResult"));
    }
 
    public event PropertyChangedEventHandler PropertyChanged;
}

A few small changes and everything still works exactly as before.

So what did we gain? Only the fact that the dependency between the PageModel and the PingServiceClient is slightly decoupled. However because we are still using concrete classes and the PingAsync() is not virtual we have gained very little.

 

Making the code more testable

In order to make the code more testable we need to start using the PingService interface instead of the PingServiceClient concrete type. So lets make some changes to the code. First of all we need to change the PageModel class to use the interface. This means we can no longer use the PingAsync function and PingCompleted event as they are part of the concrete class. Instead we have to use the BeginPing() and EndPing() functions.

One extra complication here is that the standard generated proxy makes sure the callback event is raised on the right thread, something we now have to take care of using a SynchronizationContext.

The new PageModel looks like this:

using System;
using System.ComponentModel;
using System.Threading;
 
namespace NinjectSample
{
    public class PageModel : INotifyPropertyChanged
    {
        public PageModel(PingService.PingService proxy)
        {
            _proxy = proxy;
            _context = SynchronizationContext.Current;
        }
 
        private PingService.PingService _proxy;
        private SynchronizationContext _context;
        public DateTime TheResult { get; set; }
 
        public void ExecutePing()
        {
            _proxy.BeginPing(proxy_PingCompleted, null);
        }
 
        void proxy_PingCompleted(IAsyncResult result)
        {
            _context.Post(state =>
                {
                    TheResult = _proxy.EndPing(result);
 
                    if (PropertyChanged != null)
                        PropertyChanged(this, new PropertyChangedEventArgs("TheResult"));
                }, null);
        }
 
        public event PropertyChangedEventHandler PropertyChanged;
    }
}

With this in pace we need to configure Ninject a bit so it knows which object to create as the PingService. If we forget to do so we will see a Ninject.Core.ActivationException with the following message:

Error activating PingService: no matching bindings are available, and the type is not self-bindable (or implicit binding is disabled).
Activation path:
  1) active request for PingService

 

Configuring Ninject

The way to configure Ninject is to create a module loader class derived from StandardModule and implement the Load() function specifying the dependencies like this:

using Ninject.Core;
using NinjectSample.PingService;
 
namespace NinjectSample
{
    public class PingModule : StandardModule
    {
 
        public override void Load()
        {
            Bind<PingService.PingService>().To<PingServiceClient>();
        }
    }
}

Next we need to tell Ninject which module to use by passing it into the constructor like this:

public Page()
{
    InitializeComponent();
 
    IKernel kernel = new StandardKernel(new PingModule());
    _model = kernel.Get<PageModel>();
    DataContext = _model;
}

And again everything is working again Smile

 

Adding a test service

Now we have fully decoupled the pageModel from the service we can create a test service so we execute the code without actually calling the WCF service.

First we need to create a test service like this:

using System;
 
namespace NinjectSample
{
    public class TestPingService : PingService.PingService
    {
        public IAsyncResult BeginPing(AsyncCallback callback, object asyncState)
        {
            callback(null);
            return null;
        }
 
        public DateTime EndPing(IAsyncResult result)
        {
            // Birthdate Charles Babbage
            return new DateTime(1791, 12, 26);
        }
    }
}

The code is simple and just returns a fixed date.

Next we need to tell Ninject which implementation to use. There are several ways to do this. I suppose the best is to create a specific module for testing but in this case I have taken the route of conditionally binding dependencies in a single module like this:

using Ninject.Core;
using NinjectSample.PingService;
 
namespace NinjectSample
{
    public class PingModule : StandardModule
    {
        private bool _testMode;
 
        public PingModule(bool testMode)
        {
            _testMode = testMode;
        }
 
        public override void Load()
        {
            Bind<PingService.PingService>().To<PingServiceClient>()
                .OnlyIf(p => _testMode == false);
            Bind<PingService.PingService>().To<TestPingService>()
                .OnlyIf(p => _testMode == true);
        }
    }
}

Now I can vary the behavior by just passing in true or false when creating the Ninject module.

image

 

Conclusion

Using Ninject, or another IOC container, makes it easier to test code. Of course Ninject isn’t a silver bullet here, the same effect could be achieved with manual injection. But thinking about dependencies this way makes code easier to develop and test. And why do dependency inject by hand if an IOC container like Ninject can do it for you!

Enjoy!

Source code download

Posted by Maurice | 8 comment(s)

Starting with version 9 it has become possible to embed a Flex application inside of a PDF document. Now this opens up some new exiting possibilities, that much is certain.

However I can't help thinking that virus writes will be just as happy. PDF documents are send around quite a lot and most people think they are completely safe. Now suppose some hacker embeds a malicious application in a PDF document? I have already heard stories that suggest this is already happening. Scary and not good.

So I guess I am not sure this is a good thing or not.

More info:
http://www.insideria.com/2009/01/running-flex-applications-adob.html
http://www.jamesward.com/blog/2008/11/05/portable-rias-flex-apps-in-pdfs

Posted by Maurice | 4 comment(s)

When developing WCF service the System.Web.Hosting.HostingEnvironment class is kind of useful as it will give you all sorts of information about the runtime environment of where you app is hosted.

string path = HostingEnvironment.MapPath(@"\MyFile.txt");

Now the problem is it only works when the service is hosted inside IIS, or the Cassini development server that comes with VS2008, not when the service is self hosted. Guess that makes sense but it is kind of easy to start with a WCF Service Library project template, even when you finally intend to host the service under IIS.

image

The problem is that the development service, WcfSvcHost.exe, acts as if it is running as a self hosting app and does not let you use the HostingEnvironment members.

So I guess it is better to always start with a WCF Service Application which acts more like an IIS hosted application.

image

Enjoy!

Posted by Maurice | with no comments
Filed under: , ,

I recently watched this TED video by Johnny Lee where he demonstrates some very cool usage of the Nindendo Wii. He sort of turns things around by moving the LED around and keeping the handheld receiver in a fixed location. Specially the second part where he shows a three dimensional view on a regular screen by wearing glasses equipped with LED's is amazing Smile

Enjoy!

Posted by Maurice | with no comments

I recently received a copy of IronPython in Action by Michael Foord and Christian Muirhead from Manning so I could review it so here it is Smile.

So why am I interested in a book about IronPython? Well I used to do some Python programming a number of years ago and found the language kind of nice to work with. Working with dynamic languages like IronPython relieves you from a lot of the code you have to write just to keep the compiler happy. Admittedly the compiler complains for good reason, to make you think about your code, but often you just add casts and that is all. Now I am not suggesting we dump C# and VB and all start coding all our applications in IronPython but a mix of dynamic and static certainly makes sense to me.

But more about the book.

Part 1 is about getting started with IronPython

The first few chapters provide an overview of how IronPython and Python itself came to be and the basic syntax. The basic syntax of IronPython is not difficult to learn for C# or VB developers as Python is also an object oriented language. One things that tends to freak out people when they start is that the indentation of code matters. As Michael and Christian explain this is not a bad thing but quite brilliant as everyone does so anyway for readability purposes.

Chapter 3 is quite interesting as that explains the interoperability between IronPython and regular complied .NET objects. This is an important chapter as IronPython by itself would not be very interesting, it's the combination with the full .NET framework and all the embedded functionality and the ease of working of IronPython where the sweet sport is.

Part 2 is about the code development techniques

Chapter 4 covers the basics of creating applications in IronPython. This covers design patterns like the Model View Controller (MVC) and how they apply to IronPython. Chapter 5 covers Python functions and how you can use some of the dynamic Python function features to read an XML document. In this chapter we get to see some of the using a dynamic language as compared to a static language like C#.

Chapter 6 is about working with properties. IronPython properties are somewhat different that C# or VB properties. Chapter 7 is about unit testing IronPython code. With a dynamic language like Python unit testing is even more important that with regular .NET code. Even though Python is a dynamic language it turns out that mock objects and dependency injection are still as much a part of IronPython unit testing as they are with regular .NET code. The chapter close of with a part about higher order testing and how to test the user interface.

Chapter 8 is about all the magic functions like __init__(self) that Python uses as a naming convention just like we use  interfaces in C#. Again some of the concepts might seem a little unusual but once you get used to them it is really quite easy.

 

Part 3 is about some of the more advanced concepts of using IronPython.

Chapter 9 covers programming Windows Presentation Foundation (WPF) with IronPython. With chapter 10 we are introduced into system administration using IronPython. This is an area where scripting languages are frequently used and IronPython is a perfect candidate. One popular choice for administration scripts is PowerShell and there is a whole section devoted to using PowerShell from within IronPython.

Chapter 11 is about ASP.NET and IronPython. Another interesting place to use IronPython is databases and web services, something covered in chapter 12.

Of course the DLR is part of Silverlight so IronPython is a prima candidate to use with Silverlight development as well. This subject is covered in chapter 13.

 

Part 4 is about about interoperability between IronPython by embedding the IronPython runtime inside our own .NET applications and extending IronPython with C# or Visual Basic code.

 

Conclusion

This book is a good read for all .NET developers who want to know about the new trend towards the dynamic languages and IronPython in particular. You get a good explanation what IronPython can do for you and how to go about solving every day programming problems. With the current push towards dynamic behavior, even in languages like C#, every experienced .NET developer should read this book!

Enjoy.

Posted by Maurice | 12 comment(s)
Filed under: ,