Podcasts worth checking out


Almost 3 years ago I write a post about which developer podcasts I was listening too at the time. Some have stuck and I’m now listening to more local content and even a few more non-technical shows.

Here’s what’s currently on my phone (via Podcaster);

  • Techie ones
    • The Ministry of Geek – wide range of geek topics from a couple of talkative Kiwis – sometimes funny, sometimes informative, usually rambling, always worth a listen.
    • NZ Tech Podcasts – really good wrap up and perspectives on local and international tech stuff
    • .Net Rocks – while not usually deeply technical Carl and Richard are great interviewers and know, from 10 years and 776 podcasts, how to run a show. While they do cover a range of topics there is certainly a Microsoft slant.
    • The Hanselminutes Podcasts  - good range of topics, not always Microsoft focused, even has his wife on now and then
  • Non-techie ones
    • This American Life – by far my favourite podcast at the moment, really polished production, great format. They chose a theme and wrap real life stories around it. Obviously American bias but not so much it spoils it. Great – if you listen to only one podcast this should be it!
    • RNZ – This Way Up – short sound bites from Simon Morton, well researched, interesting and good range of NZ focused content
    • Freakonomics Radio – exploring the “hidden side of everything” by the authors of the book by the same title. American based again but great range of topics, well produced.

Know any other ones that are worth a listen?

author: Tokes | posted @ Sunday, June 17, 2012 3:02 PM | Feedback (19)

What to do when developers ask you to buy software


If you’re in charge of a group of developers then you’ve probably had a conversation that starts with,

Hey, um, I was thinking, um, it would be great if I could get a licence for [insert cool software]. What do you reckon?

Let’s face it, developers love playing with the latest tools and frameworks and, while some of the best in the market are actually free, there are some that aren’t, and you’ll be faced with a decision,

Should I say yes?

Well here are my thoughts.

Always ask…

Regardless of whether it’s a $10 or $10,000 license you should always ask the person a few questions.

  • Will this software make its way into production code? – if the software is destined to be used on production code (as opposed to simply a productivity tool) then you need to make sure it fits in with your company’s existing technology stack. You don’t want 10 different components doing the same job – sure this ORM might have some cool features but if it isn’t replacing your existing ORM then it may not be worth it.
  • Have you asked the team whether anyone else needs a license too? – they might be asking for one licence but it’s usually cheaper the more licences you buy so make sure you get a good deal.
  • Don’t we already have something that does that? – make sure there isn’t some other component that does the job that the person making the request doesn’t know about. If you don’t know, make sure they ask the wider team.

Always say yes when…

Assuming your initial questions don’t rule it out, you should just say yes if,

  • There’s no reason to say no – if the only reason you can think of to say no is that you don’t personally like this product then just say yes – it’s not about you. It doesn’t matter whether you like the product, think it will improve productivity or even think it’s a waste of money – by the time you’ve tried to convince someone that they don’t need it you will have wasted more money than the cost of the licence.
  • The cost is less than $x – depending on the depth of your company’s pockets you’ll have to decide what this limit is, but for the sake of a few bucks, it is money well spent if all you’ve done is bought a little joy and happiness to some members of your team. You’ll be a amazed at the mileage you’ll get by letting your team have a few toys to play with.

To be honest, in my experience, developers tend not to ask you to purchase software that’s very expensive – so you’ll probably get to say yes a lot of the time.

 DISCLAIMER – if every member of my team comes to me asking to purchase something small tomorrow I will say no - I don’t have to follow my own advice ;-)

Maybe say yes when…

For more significant purchases, it’s not always so clear cut. Here are some things to consider.

  • It may be better than what you have – even if you have a similar component to that being requested, it’s sometimes worth considering. Say someone comes to you asking to buy a PDF conversion tool. You say, “hey, we already have something that does that in production – why do we need another component?”.  There may be some really good reasons to change – performance improvements, more complete functionality, it may address specific bugs with the existing component… you should weigh up the cost of replacing the existing component. If possible, get a trial version and get someone to spike out a solution to verify it’s going to make a difference.
  • It will make a lot of the team happy – if the purchase impacts more than the person asking for it, then regardless of how important or useful it is, you may still decide that saying yes will improve the wider team’s morale. Happy developers are more productive and stick around for longer – the cost of looking for a new developer who leaves cause they’re sick of using an old version of ReSharper can be a lot more than a few licences.

Say no when…

Hopefully you won’t have to do this too often but there are times when you should say no. Assuming the cost is significant, say no when,

  • It’s pure developer self gratification – “I can’t possibly be asked to develop without X” (spoken with a posh English accent)… it’s expensive, has no value other than a single developer’s personal pleasure.
  • What you have is fine – don’t change for the sake of it, even if there is a newer, flasher, component, it doesn’t mean you have to change/upgrade. Evaluate the benefit and don’t be afraid to say no.

I’d be interested to hear other people’s experiences here – in fact, I think this will be the first topic for the inaugural meeting of the Herders of Coders.  

 

author: Tokes | posted @ Sunday, August 28, 2011 10:18 PM | Feedback (4)

Are you a herder of coders?


If you’re a team leader or development manager or anyone who has to work with a group of developers to help them reach the finish then I bet you all share some common experiences and frustrations.

I’ve always been interested in solving problems and debating answers and am really interesting in meeting other herders to bounce ideas around with. There are some really interesting and unique challenges in this game, like,

  • How do you allow you your team to keep up with the latest shiny technology without putting the project at risk?
  • How do you motivate developers when they’re forced to work on something they’d rather not work on?
  • What value is there on sending developers on training courses or to conferences?
  • How do react when you hear, “I can’t give you an estimate, it will take as long as it takes!”?
  • How do you discover and hire awesome developers?
  • What do you do when you hire a not-so-awesome developer?
  • How do you transition from being a coder to a herder of coders?
  • Does a herder of coders need to have been a coder?

Anyway, just throwing this out there to see if there’s any interest – if you live in Wellington NZ, and think this sounds fun, then drop me a line.

And if I know you, expect me to drop you a line!

author: Tokes | posted @ Saturday, July 02, 2011 9:31 PM | Feedback (9)

Styling and DataBinding Silverlight 4.0 ListBox


In the latest version of my Podcast Aggregator application I’ve spent lots of time playing around with styling the standard Silverlight ListBox. With ultimate control of how the ListBox renders comes a reasonable level of complexity – such is life, so I thought I’d give an overview of how I did it.

This is how my list of podcasts renders;

image

There were three aspects of the listbox that I wanted to control,

  • Display - what controls/data was displayed for each item in the list
  • Interaction - what happened when users interact with the ListBox and controls – mouse over effects etc.
  • DataBinding – in particular, how best to bind to Commands in my View Model from within a ListItem which has its own DataContext
  • Smooth Scrolling – by default ListBoxes don’t scroll smoothly (at least not in Silverlight 4.0)

Display

Controlling how each item in the list should be displayed is typically controlled by defining a DataTemplate. For some reason the DataTemplate is set through a property called ItemTemplate but you get that.

<ListBox ItemsSource="{Binding Podcasts}" 
         ItemTemplate="{StaticResource PodcastListDataTemplate}">
</ListBox>

I’ve defined my DataTemplate in a resource dictionary file so can simply refer to it from my ListBox definition.

<!-- This data template determines how each item in the list should be rendered -->
<DataTemplate x:Key="PodcastListDataTemplate">
    <Grid Background="White" >
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="30"/>
            <ColumnDefinition  />
            <ColumnDefinition Width="105"/>
            <ColumnDefinition Width="105"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="30"/>
            <RowDefinition Height="2"/>
        </Grid.RowDefinitions>
 
        <!-- Background when unread -->
        <Rectangle x:Name="backgroundUnread" Visibility="{Binding Read, Converter={StaticResource InvisibilityConverter}}" Grid.RowSpan="3" Fill="White"  Grid.ColumnSpan="4" />
 
        <!-- Right fade when unread -->
        <Border x:Name="fadeUnread" Margin="0,1" Grid.RowSpan="3" Visibility="{Binding Read, Converter={StaticResource InvisibilityConverter}}" Grid.Column="1"  IsHitTestVisible="False" HorizontalAlignment="Right" Width="97" Canvas.ZIndex="1">
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,.5" >
                    <GradientStop Color="Transparent" Offset="0.258"/>
                    <GradientStop Color="White" Offset="0.722"/>
                </LinearGradientBrush>
            </Border.Background>
        </Border>
 
        <!-- Background when read -->
        <Rectangle x:Name="backgroundRead" Visibility="{Binding Read, Converter={StaticResource VisibilityConverter}}" Grid.RowSpan="3" Fill="#FFE5E5E5"  Grid.ColumnSpan="4" />
 
        <!-- Right fade when read -->
        <Border x:Name="fadeRead" Margin="0,1" Visibility="{Binding Read, Converter={StaticResource VisibilityConverter}}" Grid.RowSpan="3" Grid.Column="1"  IsHitTestVisible="False" HorizontalAlignment="Right" Width="97" Canvas.ZIndex="1">
            <Border.Background>
                <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,.5" >
                    <GradientStop Color="Transparent" Offset="0.258"/>
                    <GradientStop Color="#FFE5E5E5" Offset="0.722"/>
                </LinearGradientBrush>
            </Border.Background>
        </Border>
 
        <!-- Dotted divider -->
        <Rectangle x:Name="divider" StrokeDashArray="5,2" Stroke="#FFDADADA" Grid.ColumnSpan="4" Grid.RowSpan="3"  />
        <Border x:Name="divider2" BorderBrush="White" BorderThickness="1,1,1,0" Grid.ColumnSpan="4" Grid.RowSpan="3" />
 
        <!-- Star -->
        <HyperlinkButton x:Name="starHyperlink" VerticalAlignment="Center" HorizontalAlignment="Center" Command="{Binding ListViewModel.ToggleStar, Source={StaticResource Locator}}" CommandParameter="{Binding}" Style="{StaticResource HyperLinkImages}">
            <local:Star Height="15" Width="15" Background="Black" Starred="{Binding Starred, Mode=TwoWay}" />
        </HyperlinkButton>
 
        <!-- Title (link to details) -->
        <HyperlinkButton x:Name="titleHyperlink" HorizontalAlignment="Left" Grid.Column="1" Foreground="{StaticResource TextForecolour}" FontSize="13" FontWeight="Bold" VerticalAlignment="Center" IsTabStop="False" CommandParameter="{Binding}">
            <TextBlock Text="{Binding Title}"  />
        </HyperlinkButton>
 
        <!-- Channel Name -->
        <TextBlock Margin="15,0,0,10" Grid.Column="1" Grid.Row="1" Text="{Binding ChannelName}" FontSize="13" Foreground="#FF8B8888" VerticalAlignment="Center"/>
 
        <!-- Published Date -->
        <TextBlock Margin="0,2,0,0" Grid.Column="2" Grid.Row="0" Text="{Binding Published, StringFormat=MMM dd HH:mm}" FontWeight="Bold" FontSize="13" Foreground="{StaticResource TextForecolour}" VerticalAlignment="Center" />
 
        <!-- Download Progressbar -->
        <HyperlinkButton Visibility="{Binding IsDownloading, Converter={StaticResource VisibilityConverter}, Mode=OneWay}" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" CommandParameter="{Binding}" ToolTipService.ToolTip="Click to cancel" Canvas.ZIndex="10" Style="{StaticResource HyperLinkImages}">
            <Grid HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="2" >
                <Rectangle  HorizontalAlignment="Left"  Width="100" Height="18" Fill="#FFA19F9F" />
                <Rectangle Width="{Binding DownloadProgressPercentage}" Height="18" Fill="#FF7C7777" HorizontalAlignment="Left" Visibility="{Binding IsDownloading, Converter={StaticResource VisibilityConverter}, Mode=OneWay}"/>
                <TextBlock VerticalAlignment="Center" HorizontalAlignment="Center" Text="{Binding DownloadProgressText, Mode=OneWay}" FontSize="9" Foreground="White" />
                <Border Width="100" Height="18" BorderThickness="1" BorderBrush="#FF7C7777" />
            </Grid>
        </HyperlinkButton>
 
        <!-- Download button -->
        <HyperlinkButton Visibility="{Binding CanDownload, Converter={StaticResource VisibilityConverter}, Mode=OneWay}" Grid.Row="0" Grid.Column="3" HorizontalAlignment="Center" VerticalAlignment="Center" CommandParameter="{Binding}" Canvas.ZIndex="10" Style="{StaticResource HyperLinkButton}" Content="DOWNLOAD">
            <!-- bind to command throught Locator -->
        </HyperlinkButton>
 
        <!-- Downloaded -->
        <TextBlock Visibility="{Binding FileExists, Converter={StaticResource VisibilityConverter}}" Grid.Row="0" Grid.Column="3" VerticalAlignment="Center" HorizontalAlignment="Center" Foreground="Gray" Text="DOWNLOADED">
                <ToolTipService.ToolTip>
                    <Grid>
                        <StackPanel>
                            <TextBlock Text="file:" Style="{StaticResource Label}"/>
                            <TextBlock Width="100" Text="{Binding FullPath}" TextWrapping="Wrap"/>
                        </StackPanel>
                    </Grid>
                </ToolTipService.ToolTip>
            </TextBlock>
 
        <!-- Play button -->
        <HyperlinkButton x:Name="play" Grid.Column="3" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Opacity="0.2" Style="{StaticResource HyperLinkImages}" CommandParameter="{Binding}" >
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter">
                    <ei:ChangePropertyAction PropertyName="Opacity" Value="1"/>
                </i:EventTrigger>
                <i:EventTrigger EventName="MouseLeave">
                    <ei:ChangePropertyAction PropertyName="Opacity" Value="0.2"/>
                </i:EventTrigger>
            </i:Interaction.Triggers>
            <Grid>
                <Ellipse Height="20" Width="20" Margin="0,0,2,0" Stroke="Black" VerticalAlignment="Bottom"/>
                <ed:RegularPolygon InnerRadius="1" PointCount="3" Stretch="Fill" Stroke="Black" Width="10" Height="10" RenderTransformOrigin="0.5,0.5">
                    <ed:RegularPolygon.RenderTransform>
                        <CompositeTransform Rotation="90"/>
                    </ed:RegularPolygon.RenderTransform>
                </ed:RegularPolygon>
            </Grid>
        </HyperlinkButton>
        
    </Grid>
</DataTemplate>

I’ll leave you to look through the XAML but it’s just that, XAML, and can contain anything you like.

There are a couple of things in there that are worth noting though.

  • Visibility/Invisibility Converters are used to hide/show elements based on Boolean properties on the podcast entity I’m binding each item to. I’m sure someone out there has a tidier way to do this but this is simple and works.
  • To provide hover-over effects for individual controls (for example, the Play control) I’m using EventTriggers that come with Expression Blend.

While I’m used to doing most of my Silverlight work in Visual Studio and directly in XAML, I have to admit that working with templates and styles is a lot easier in Expression Blend. For example, even if your template is defined in another file (as is the case for me) you can edit the XAML and see the effects within the designer.

image

If you only defined the DataTemplate and ran the application you’d see something that looked like;

image

Which is getting there but has a few problems. Firstly, the ListItems are not stretching out to fill the width of the ListBox and secondly the hover-over/selected effects don’t really work with as I’d like. Both of these things are sorted by looking at the ItemContainerStyle.

Interaction

To control the style of the container that hosts each ListItem and how it should react to user interaction you need to set the ItemContainerStyle (again – I’m not crazy about this name).

Here’s the one I defined.

<Style x:Key="PodcastListBoxItemStyle" TargetType="ListBoxItem">
    <Setter Property="Padding" Value="0"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <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}" d:DesignWidth="930" d:DesignHeight="140">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="CommonStates" >
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="mouseOverHighlight" />
                                    <DoubleAnimation Duration="0" To="0.385" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="readHyperlink" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="contentPresenter"/>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="SelectionStates">
                            <VisualState x:Name="Unselected"/>
                            <VisualState x:Name="Selected">
                                <Storyboard>
                                    <DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="selectedHighlight" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="FocusStates">
                            <VisualState x:Name="Focused" />
                            <VisualState x:Name="Unfocused"/>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
 
                    <!-- Read/Unread Toggle -->
                    <HyperlinkButton Margin="5,9,0,0" Command="{Binding ListViewModel.ToggleRead, Source={StaticResource Locator}}" x:Name="readHyperlink" CommandParameter="{Binding}" Style="{StaticResource HyperLinkImages}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.ZIndex="2" Opacity="0" Width="20" Height="20" ToolTipService.ToolTip="Read/UnRead"  >
                        <Canvas>
                            <Rectangle x:Name="unread" Height="12" Width="12" Stroke="Black" />
                            <TextBlock Margin="2,-1,0,0" FontSize="10" Foreground="Black"><Run Text="R"/></TextBlock>
                        </Canvas>
                    </HyperlinkButton>
 
                    <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" OpacityMask="Black"/>
 
                    <Rectangle Width="5" Margin="0,2,0,2" HorizontalAlignment="Left" x:Name="mouseOverHighlight" IsHitTestVisible="False" Opacity="0" Fill="#FFD4D4D4"/>
 
                    <Rectangle Width="5" Margin="0,2,0,2" HorizontalAlignment="Left" x:Name="selectedHighlight" IsHitTestVisible="False" Opacity="0" Fill="#FFB2B2B2"/>
 
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

So I solved the problem of each ListItem not stretching by setting the HorizontalContentAlignment to Stretch.

And the VisualStateManager stuff controls the animations that occur when the state changes through user interaction.

The only thing here that’s slightly unusual is that I have also added a set of control (rectangle with the letter R in it) that the user can click to toggle a podcast as read/unread. The reason I put this in the ItemContainerStyle.Template (rather than the DataTemplate) is that I wanted it to appear and disappear as a user moused over a ListItem – this seemed the easiest way to do this. The DataBinding technique is the same as for the DataTemplate (see below).

DataBinding

The DataBinding within the templates is pretty straightforward in most cases because we are binding directly to the podcast object that each ListItem’s DataContext is set to. The only thing that takes a bit more thought is how to bind to a Command that is in the DataContext (ViewModel) of the parent of the ListBox. Since the ListBoxItem has no direct knowledge of it’s parent’s DataContext we have to take a different approach.

WPF (of which I have no real experience!) apparently allows you to use RelativeSource with FindAncestor to do exactly what we want – i.e. find our ViewModel from an Ancestor control – but Silverlight 4.0 doesn’t yet have this.

One approach is to use, Colin Eberhardt’s extended implementation of RelativeSource binding that supports FindAncestor, but if you’re following the pattern of using a static View Model locator (e.g. like MVVMLight uses) then it’s a bit easier.

As you’ll see in more detail in the download I have a Locator class that contains a ListViewModel property that returns a static instance of my View Model – this means that whoever calls it will get access to the same instance.

Which means that from within my ItemContainerStyle.Template (or anywhere for that matter) I can write something like,

<HyperlinkButton x:Name="readHyperlink" Command="{Binding ListViewModel.ToggleRead, Source={StaticResource Locator}}" CommandParameter="{Binding}" Style="{StaticResource HyperLinkImages}" HorizontalAlignment="Left" VerticalAlignment="Center" Canvas.ZIndex="2" Opacity="0" Width="18" Height="18"  ToolTipService.ToolTip="Read/UnRead">
    ...
</HyperlinkButton>

Which binds the Command of the Hyperlink to the ToggleRead property of my ListViewModel – easy.

Smooth Scrolling

The last thing I wanted to achieve was to make my list scroll smoothly – this is actually pretty easy.

The ItemsPanel property of the ListBox controls how the outer container of the ListBox is constructed. By default ListBoxes use a VirtualizingStackPanel that has some smart behaviour to make working with large lists perform better. The consequence of this performance improvement is that the scrolling on the ListBox will jump from one item to the next rather than scrolling smoothly.

You can override this behaviour – if smoothness out scores performance – by defining your own ItemPanelTemplate to use a standard StackPanel.

<ItemsPanelTemplate x:Key="PodcastItemPanelTemplate">
    <StackPanel/>
</ItemsPanelTemplate>

Finally

So now with all the templates configured we just reference them from the ListBox and we’re there.

<ListBox ItemsSource="{Binding Podcasts}" 
         ItemTemplate="{StaticResource PodcastListDataTemplate}"
         ItemContainerStyle="{StaticResource PodcastListBoxItemStyle}"
         ItemsPanel="{StaticResource PodcastItemPanelTemplate}"
         ScrollViewer.HorizontalScrollBarVisibility="Disabled"
         >
</ListBox>

The only additional thing I added was to disable the horizontal scrollbar so that my list always took up the entire page width even if the contents of my columns were long.

And that’s it – have a look at the source to get it up and running and have a play.

author: Tokes | posted @ Sunday, February 13, 2011 8:19 PM | Feedback (9)

Wellington Silverlight User Group – oData, Azure and Silverlight


Next week Karl Farrand, from 7G, will be taking us through how Silverlight, oData and Azure combine to solve some common scenarios when building rich internet applications.image

oData (aka Astoria and ADO.Net Data Services) is something Microsoft has been promoting for a while and is a response to the industry's demands for a more open, less proprietary approach to accessing and persisting data.

And Azure – well, you probably know what that is, and if not come along and find out.

For most of the last decade Karl has designed and built specialised tax software for large accounting firms such as Deloitte and EY. He currently works for 7G, a SaaS provider specialising in tax calculation and reporting software. 7G use Silverlight extensively in their product offering to provide their clients with a rich, easily deployable and secure user interface.

Find out more.

author: Tokes | posted @ Monday, February 07, 2011 4:57 PM | Feedback (7)

Silverlight 4 – Simple Configuration Manager


Unlike the full framework, Silverlight 4 doesn’t have built in support to read from an application configuration file – the System.Configuration.ConfigurationManager isn’t part of the framework. Of course, Silverlight is a bit different to other applications where users may need to gain access to an app.config file but nevertheless it’s sometimes nice to store and retrieve configuration data in a familiar way.

So here’s a quick and easy way to do it.

Add an XML file to the root of your Silverlight project, rename it to app.config and set it’s build action to Resource.

image

Whack in some appSettings in the same way you would a normal configuration file.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <appSettings>
    <add key="serviceUrl" value="http://myservice.com"/>
    <add key="guestAccountEmail" value="guest@mycompany.com"/>
  </appSettings>
</configuration>

Now create your very own ConfigurationManager class (note, you’ll need to add have a reference to System.Xml.Linq).

using System;
using System.Windows;
using System.Collections.Generic;
using System.Windows.Resources;
using System.IO;
using System.Xml.Linq;
using System.Reflection;
 
namespace GoogleReader.API.Tests
{
    /// <summary>
    /// Access appSettings from a configuration file
    /// </summary>
    /// <remarks>Your appConfig file must be in the root of your applcation</remarks>
    public static class ConfigurationManager
    {
 
        static ConfigurationManager()
        {
            AppSettings = new Dictionary<string, string>();
            ReadSettings();
        }
 
        public static Dictionary<string, string> AppSettings { get; set; }
 
        private static void ReadSettings()
        {
            
            // Get the name of the executing assemby - we are going to be looking in the root folder for
            // a file called app.config
            string assemblyName = Assembly.GetExecutingAssembly().FullName;
            assemblyName  = assemblyName.Substring(0, assemblyName .IndexOf(','));
            string url = String.Format("{0};component/app.config", assemblyName);
 
            StreamResourceInfo configFile = Application.GetResourceStream(new Uri(url, UriKind.Relative));
 
            if (configFile != null && configFile.Stream != null)
            {
                Stream stream = configFile.Stream;
                XDocument document = XDocument.Load(stream);
 
                foreach (XElement element in document.Descendants("appSettings").DescendantNodes())
                {
                    AppSettings.Add(element.Attribute("key").Value, element.Attribute("value").Value);
                }
            }
        }
    }
}

And write the code you’re used to.

 
// Give me a url please
string serviceUrl = ConfigurationManager.AppSettings["serviceUrl"];
 

Easy.

author: Tokes | posted @ Sunday, January 23, 2011 11:15 AM | Feedback (28)

Asynchronous Tests in Silverlight – Run Callbacks on UI Thread


I’ve just started to set up some unit tests for a pet project I’m playing with to wrap the GoogleReader.API for Silverlight clients.

Once you’ve downloaded the latest Silverlight Toolkit you’ll have access to the Silverlight Unit Testing Framework – the great thing about this framework is that it makes writing tests that call asynchronous methods a breeze – well, I was actually becalmed for a while until I worked out a few tricks to get things working.

The framework lets me write tests that look something like,

[TestClass]
public class CommandTests: SilverlightTest
 
{
    [Asynchronous]
    [TestMethod]
    public void Can_Login()
    {
        ConnectCommand command = new ConnectCommand();
 
        command.BeginConnect("myemail", "mypassword", (result) =>
        {
            Assert.IsTrue(result.Result && result.Sid != null && result.AuthToken != null, "Can't log in");
            EnqueueTestComplete();
        });
    }
}

You simply add the Asynchronous attribute and make sure you call EnqueueTestComplete to let the framework know the test is complete. Easy.

Except every time my test failed Visual Studio would treat this as an unhandled exception, my test would bomb but it wouldn’t show up as a failed test in the test UI harness.

It turned out not to be the fault of Visual Studio or the framework – it was me!

My implementation of the BeginConnect method ultimately had some code that did,

if (callback != null)
{
    callback(resultSet); 
}

Which resulted in my callback method being executed on the thread of my asynchronous method call rather than on the UI thread. This in turn meant the unit testing framework (which is running on the UI thread) couldn’t handle the failed assertions. Bingo!

One solution was to re-implement my component’s code to,

if (callback != null)
{
    Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
            callback(resultSet);
        });
}

Which I’m not entirely comfortable with since my component is not a UI component so shouldn’t really have to deal with this.

The alternative was for my test method to make the assertions on the UI thread by changing them to,

[Asynchronous]
[TestMethod]
public void Can_Login()
{
    ConnectCommand command = new ConnectCommand();
    command.BeginConnect("myemail", "mypassword", (result) =>
    {
        TestPanel.Dispatcher.BeginInvoke(() =>
            {
                Assert.IsTrue(result.Result && result.Sid != null && result.AuthToken != null, "Can't log in");
                EnqueueTestComplete();
            });
    });
}

Where TestPanel is the UI element hosting the test results and is exposed through the PresentationTest base test class.

This approach is probably cleaner and could be abstracted more – perhaps into a specialisation of the PresentationTest class itself.

Anyone got any better ideas?

author: Tokes | posted @ Thursday, January 20, 2011 10:38 PM | Feedback (5)

Google Reader API – Advanced Search


As part of my playing around with the GoogleReader API I needed to be able to search for items beyond a simple keyword search.

Since my last post I’ve extended my asynchronous C# wrapper (get latest code here) so the syntax has changed slightly  (took a lead from Simone to use lambdas – much better) and I’ve strongly typed all the responses, but you’ll get the idea.

Google expose a simple keyword search – under the hood you actually need to make two requests; a GET request to http://www.google.com/reader/api/0/search/items/ids?q=keyword… which will return the ids of the items found. Then you POST the ids to http://www.google.com/reader/api/0/stream/items/contents which returns the results.

This is all wrapped up for you by the following code which searches for anything to do with “Silverlight” in my Starred items.

GoogleReader.Search(“Silverlight”, ItemStateEnum.starred, (result) =>
    {
        // Do something with the items
        List<Item> items = result.Items;
 
    });

Or you can search over specific feeds with something like,

GoogleReader.Search("Silverlight", new FeedDescriptor(new Uri("http://feeds.timheuer.com/timheuer")), (result) =>
    {
        List<Item> items = result.Items;
    
        //...
    });

Or search over labels (tags and folder names),

GoogleReader.Search("Silverlight", new LabelDescriptor("Podcasts"), (results) =>
    {
        List<Item> items = results.Items;
    });

But what I actually wanted to be able to do was to search for any item that was a podcast, or more precisely contained some media – it may or may not have been tagged as such.

To do this and more complex searches is not currently possible via the Google Reader API so I created another overload for the search that takes a predicate.

So you can write something like,

GoogleReader.Search(
    (item) =>
    {
        // Write any method here that works with Item and returns a bool
        return (item.Enclosure != null || item.MediaGroup != null);
    },
    ItemStateEnum.reading_list,
    (result) =>
    {
        List<Item> items = result.Items;
    });

which will search over all my items for anything which contains some media.

This method will do a recursive search pulling back a set of items, searching through them and repeating until a set number of results have been found. This will obviously take more time to process so take care.

You can control how the search works by passing in additional filter options.

FilterOptions options = new FilterOptions();
options.MaximumNumberofResults = 10;
options.MaximumSearchableItems = 300;
options.SearchPageSize = 100;
 
GoogleReader.Search(
    (item) =>
    {
        // Write any method here that works with Item and returns a bool
        return (item.Enclosure != null || item.MediaGroup != null);
    },
    options,
    ItemStateEnum.reading_list,
    (result) =>
    {
        List<Item> items = result.Items;
    });

This will ensure that the search will complete once 10 results are returned or you search has gone through 300 items (100 at a time).

Full source code can be found here.

author: Tokes | posted @ Thursday, January 13, 2011 4:57 PM | Feedback (1)

Google Reader API – C# Asynchronous Wrapper


I wrote this wrapper around the Google Reader API recently that might be useful if you’re trying to do the same thing – especially if you’re doing it from Silverlight where you need to work asynchronously and across a reduced .NET framework stack. Quite a bit of my early investigations were based on the great effort put in by Martin Doms – his stuff still stands apart from the security stuff which Google have since changed.

The component I created is pretty easy to use.

Start by connecting to Google Reader using your normal email and password.

public class TestReader
{    
    private Reader GoogleReader { get; set; }     
    public TestReader()    
    {        
        GoogleReader.SignIn(email, password, (result) =>
        {
            if (result.Result)
            {
                // Do something...
            }
        });
    }
}

Once connected you can start calling the other methods – each of which accepts a callback arguement to receive the (strongly typed) results on. For example, to retrieve 20 unread items,

GoogleReader.GetUnreadItems(20, (result) =>
    {
        foreach (Item item in result.Items)
        {
            // Do something with each item            
        }
    }
);

You can also edit individual items by passing in the id and streamId of the item (accessed from the results of a call to one of the list methods).

GoogleReader.StarItem(id, streamId, (result) =>
{
    if (result.Result)
    {
        // Do something - it worked!
    }
});

There are lots of other commands I’ve implemented (and more that could be done) but this should give you a good starting place.

I’ve also added a simple test application that lets you see what’s going on.

image

I’ve only tested this in Silverlight 4 and VS 2010 but it should easily adapt to any future Silverlight releases or non-Silverlight solutions.

Get the source code here

author: Tokes | posted @ Wednesday, January 05, 2011 2:07 PM | Feedback (8)

Silverlight Installation Experience – User Group Meeting


Just a reminder for anyone interested in learning more about how to improve the way people install, upgrade and load your Silverlight applications – most applications out there rely on the default options which result in the somewhat proprietary and unfriendly user experiences like,

image imageimage 

It’s not that hard to take control of all these and do even more to add a professional edge to your applications.

If you’re interested head on over to our user group site, sign up and set a date for Wednesday 17 Nov – 6:00pm @Xero.

author: Tokes | posted @ Saturday, November 13, 2010 10:33 AM | Feedback (13)