Wednesday, December 17, 2008

WPF Command.Text

I'm not sure why it never occurred to me before, but this might help clean up some of the code out there where buttons are bound to commands.

The standard way I have been binding to buttons is to set the command and then set the content like one of the following:

<Button x:Name="PlayButton" 
        Command="{Binding PlayCommand}">Play</Button>
<Button x:Name="Help"
        Command="ApplicationCommands.Help" 
        Content="{Binding RelativeSource={RelativeSource Self}, 
                 Path=Command.Text}" />

Which in the first case just repeats the word "Play" three times and in the second case is just plain ugly and not something you would want to reproduce everywhere just to infer the content from the Command when typing "Help" would be easier to type and to read. Yeah obvious, now that I spell it out to myself. I should just set my default style on my buttons to be something like this and include it in my skins/app.xaml

<Style TargetType="Button">
  <!--Default Button content to be the Text provided from the Command.-->
  <Setter Property="Content" 
          Value="{Binding RelativeSource={RelativeSource Self}, 
           Path=Command.Text}"/>
</Style>
Now all buttons will try to set their content to the Command's Text property if it has one (RoutedUICommands do). If the command doesn't expose a Text Property or the button is not bound to a command, well I still was going to have to code some content anyway so no big loss.

What's in a name?

A rose by any other name....

Well not in software Romeo. Colin at Abstract.com posted an entry on obvious comments and how they probably indicate rubbish design/naming of methods and variables.

I am just stumbling into this kind of thing now. The client has asked for "Attachments" to be added to an entity in a system I am working on. When they say attachments they just want to upload documents and them to be linked to the entity. Sounds reasonable. So a developer has gone off and created an Attachment class.

I might be being picky here, but to me there is a subtle difference between Attachment, File and say Document or Image. Attachment describes a relationship, File describes an entity representing a file. You may sub class File with Document which might expose a Title, Subject Author properties. You may sub class File with Image and provide Width & Height Properties. But I doubt you would ever have a type of Attachment. If I wanted to add attachments to an entity I could call its void AddAttachment(File attachment) method with my uploaded document, image or simple file. To retrieve them I might use

IEnumerable<File> ListAttachments()
method or maybe just a simple
IEnumerable<File> Attachements
property.

Yeah its picky. Instead of just poking fun at someones design I may try to resurect an old design I had for this space (cheap and nasty DMS), and post it for public mockery.

Google SketchUp

Following on from the Balsamiq post, I stumbled upon Google SketchUp. I dont think it will be much use for designing software (well at least not 2d software) but looks fun. At version 7 I figure as usual I am well behind the pulse of the market.

Tuesday, December 16, 2008

Web security

I recently helped a friend evaluate a web she had developed for her. The business is essentially a web based business, but she is not a web developer herself so had the development outsourced to a reputable local web design company. At first she was happy with the result them some things were going a miss and one of her business partners who fancied themselves as a hobbyist nerd found a security hole. This raised some concerns and then she approached them and they had it fixed up. When Alice* told me about this I was rather uncomfortable with the whole scenario. How is a hobbyist able to identify security holes in a web site?!

Alice sensed my concern (probably due to the swearing and head in hands), and asked if I was able to have a quick review of the site. The good news was they fixed up the SQL Injection vulnerability. Bad news was, that was about it. Now I am a professional developer working exclusively in the .NET space. I am aware of certain security issues and would place myself as a somewhat knowledgeable in areas of security, but by no means a Bruce Schneier or Keith Brown. It took me 4 hours with the use of notepad, skydrive and a browser (ie free and available software) to have cross-site scripting attacks up and running. I was able to fetch my own password from the cross site script and also hijack my session. Having done this I flicked Alice an email and let her know the bad news.

This made me think, are the web developers out there writing secure applications yet? In fact is anyone? The last place I worked, they commissioned a guy to write his own custom federated security model for an internal system. Yeah the words Federated and Internal seem to conflict eh. Well that system took only 90mins to hack open. Irony is that Windows Authentication would have been more secure and faster. The place I am currently working they have a recommendation to store username and password pairs in *.config files when trying to authenticate across multiple servers (Kerberos hop anyone?). This obviously is worrying.

So I thought I would throw together a refresher list of things you need to do to make your system, well not insecure.

  1. Don't store passwords. That's right you don't need them. Ideally you should be using an authentication system (OpenAuth, AD/LDAP etc.) but if you need to roll your own you only need a salted hash of the password to perform a comparison for authentication. Storing passwords is just asking for trouble. If you consider all of the systems the users have to log in to there is a very high chance that either their password is the same everywhere or they have a pattern for picking passwords. If I can hack your Database of passwords then not only can I hack you site, but there is a good chance that I can now hack these user's accounts in gmail, facebook, linkedin etc and even worse...bank accounts or work accounts.
  2. Sanitise your inputs, and even better don't ever "evaluate" user input as code this comic is a great parody of this. An easy target of this is SQL Injection attacks. SQL Injection attacks just make me shudder.
  3. As above, only use parameterised SQL. This doesn't favour SPs or dynamic SQL. I have seen vulnerable code in both, but neither needs to be vulnerable.
  4. In web development, never display foreign or user input to the screen with out encoding it. This is how session hijacking occurs. (basically repeating myself on evaluating user input)
  5. Use HTTPS for login screens or any screen that passes private/protected data.
  6. .Net developers should strong name critical assemblies. If you don't, some one can basically use reflector to recreate your assembly and replace your implementation with theirs. I have used this to replace the assembly that performed the login. My implementation was identical except that I logged passwords to a location that I could read later. Interestingly the compiled assembly was identical in size even though I had added code. Changing the file created/modified date to the original wasn't a hassle so no one would be any wiser.

Rocky H used to have a brilliant video on "Assembly Hijacking" which showcased a combination styles of attacks to basically take over a server. The link I have (and the ones Google finds) are dead links. I have emailed him to see if we can get it back on line. Required viewing.

I hope the information here helps someone. If you dont know what any of the jargon above means in detail then there is a great chance that you are writing insecure code. Just Google/Wiki the phrase you don't know, it will take you 10minutes to learn what it is and how to prevent it. Otherwise feel free to ask.

*Alice is not her real name

Friday, December 12, 2008

balsamiq - UI Mock tool

Check out this neat little UI Mocking tool. http://www.balsamiq.com/ Really simple and fits with my preference for "Crayon drawing" UI mocks. My problem with life like mocks (contradiction?!) is that you end up being bound to the UI instead of the functionality that the client wants.

Tuesday, November 18, 2008

WPF Back to Basics - Panels

Something I am noticing amongst my WPF peers is limited knowledge of the layout tools available to us in WPF. Most of us come from a Win Forms or ASP.NET background to relate to a few concepts:

  1. Absolute positioning
  2. Table positioning

I have very limited experience in Win Forms programming but all the stuff I have done with has been absolute positioning eg this control is x pixels from the Left/Right and y pixels from Top/Bottom. In my ASP.NET career I have seen plenty of way to create layout from everyone's first love; tables, to frames, IFrames, Lists and divs (remember Layers anyone?).

Well WPF really brings a lot more to the table than that lot of layout options. Remember that HTML has kinda evolved to being what it is with CSS tacked on to help layout. It originally was a markup language for describing content not really for fancy presentation. WPF however was built ground up for fancy presentation.

Lets look at some of the layout options we have available to us out of the box and when each would be useful:

Grid

The grid is similar to a Table in HTML, similar but not the same. In a grid you specify how many rows and columns the grid will have. You then set an attached property on each of the child elements specifying which row and column (zero based index) it belongs to. Failure to do so will default in the value of 0 being assumed meaning it will displayed in the first row/column.

Grid also has the interesting feature that allows you to stack things in a z index. For example if you specify two things to appear in the same cell then the elements are piled on top of each other with the last element specified being on top. This can be useful in some scenarios, but generally is a mistake when a dev forgets to specify the correct column and row attached properties

When to use Grid?

I find that the Grid has been most useful to me when I need to display a form to fill in. Generally I have a Label in column 0, the field in column 1 and maybe a validation message in column 3. It also offers star notation for its column and row size values which can be nice for dynamic resizing of layouts.

Canvas

Canvas is a similar to absolute positioning in HTML/CSS. You just provide Left/Right and Top/Bottom coordinates. There are no boundaries so you provide any kind of values eg negative or very large. I find the canvas the least useful panel for the work I do. However it is showcased very nicely in the FamilyShow application by Vertigo.

When to use Canvas?

I would use canvas if I wanted to throw stuff on to a conceptual whiteboard or desktop. This would be great where the user could just drag things around and not have to be constrained by a less organic structure like a grid.

StackPanel

StackPanel is one of the simplest but best tools in your layout panel arsenal. It simply stacks its children one after the other in the orientation you specify. The  Orientation options are Horizontal and Vertical (the default). In a web world this would be like just placing a bunch of items in successive black elements (div tags). If we set the orientation to Horizontal then it would more similar to using span tag except in WPF the StackPanel will not wrap when it runs out of room. Also note that the StackPanel will take up as much room as it needs, but never any more room than it needs, so don't use StackPanel where you want a fill effect.

When to use the StackPanel?

Everywhere! ;-) I find that the StackPanel is great for Templates where I may want to stack a Header, a summary and a description for example. There are also useful when bundling text blocks together quickly where you may want "X by Y pixels" you can stack horizontally four text blocks of which two are bound to Width and Height properties.

WrapPanel

The WrapPanel is the answer when the StackPanel has scrolled of the edge of the screen because it has taken too much room. As I pointed out above the StackPanel will also take the space it needs, the WrapPanel however will respect one dimension and wrap to a new line of controls when it runs out of room in that dimension.

When to use the WrapPanel?

My favourite use of the WrapPanel is to replace an ItemPanelTemplate for an ItemsPanel property in an ItemsControl. Sorry if that makes very little sense. Lets provide some background; when you use an ItemsControl (or one of its inherited controls like ListBox, ListView, Selector etc) by default all of the Items it displays are just display one after the other in a vertical direction. That is because the implementation uses a StackPanel do do its dirty work. However by changing the ItemPanelTemplate we can have it use a WrapPanel instead. So? Well this is really sweet for when we want to display things like Thumbnail pictures. When we use the WrapPanel we get an effect like in Windows Explorer when you view images within a folder as thumbnails which displays images left to right and then when there is no more space it wraps to the next line and continues showing the images. If there are too many images for the page then a vertical scroll bar will be displayed.

DockPanel

DockPanel is one of the un-sung hero's of WPF layout. The general idea behind the DockPanel is that the control will fill the area it is given, and then allow its children to "dock" themselves to one of it's four sides (Left, Right, Top and Bottom). DockPanel uses a first-in-first-served notion. If I have a DockPanel and the first child of the DockPanel wants to dock to the right, it will take up as much horizontal space as it requests and 100% of the height of the DockPanel. If the next child wanted to dock to the Bottom then It would recieve as much vertical space that it needed and the remaining horizontal space left from the first child. Generally the last child is provided the remaining available space.

When to use the DockPanel?

The DockPanel is an underused panel in my experience. Many complex implementations using Grids with fixed column and row widths and then an Auto sized column and row in the middle for content should have used a DockPanel. I would imagine a large majority of applications now have a toolbar at the top, a status bar at the bottom, some menu system down the left and/or right side. This common layout just screams DockPanel.

 

Other notable mentions...

While this post is mainly about panels, the intention is to uncover the possibilities before you by having a better knowledge of WPF, because of that I think it is worth talking about some other controls that could be useful.

TabControl

Now I bet the first thing you will think is "I know what a tab control is...next.", but stop for just a second. With the power of WPF and it's lookless control sub-system I have seen some talented WPF people put together crazy solutions together where a stylised TabControl would have been fine. Essentially the TabControl is a Selector of headered controls. Select one Head and its contents show.

When to use the TabControl?

When ever you have a piece of functionality that has a set of buttons that stay visible, but pressing on one of them shows a view and hides another view, please consider tab control. An example that many could relate to would be the buttons down the left side of Outlook. When you select the Mail Button, the Mail Button is displayed as selected and the Mail content shows. Now this doesn't look like a normal TabControl but the effect is the same.

Viewbox

I thought I might make mention of this funky control. The Viewbox gives this cool scale effect that most would only associate with the Image control. As with an Image control that allows a Stretch property to be set so that it can scale out to fill the space it has been provided, the Viewbox can wrap another control to provide the same feature. Very cool.

When to use the Viewbox?

Use the view box when you want a control to always be completely visible and scale to the space it has been provided.

Toolbar / ToolbarTray

Toolbar is one of those useful controls to use to give common functionality to your application. Many Microsoft application have a toolbar in them. Visual Studio is a very good example of ToolbarTray and Toolbar usage. VS has an area defined that can house ToolBars. The user can choose which toolbars to show and hide and can even drag them around to change the order they are displayed. You get this for free if you use the ToolbarTray and add Toolbars to it.

When to use the ToolbarTray and Toolbar?

Use the ToolbarTray and the ToolBar controls to get similar functionality to Visual Studios toolbar features. Users feel comfortable with controls the already know and you will have less code to write. remeber you can always change the styles to jazz it up if you need.

Ribbon

The Microsoft Ribbon is now available. I have not played with it myself yet but there are videos from PDC that demo how you can code against the current release. Watch this space...

Thursday, November 13, 2008

Charity work...

Tamir Khason has recently announced that he has left the consulting field, however is still willing to provide his services for the benefit of charity. Much karma too him.

Wednesday, November 12, 2008

How C# 3.0 helps you with creating DSL

Carrying on with the last post on how Method Chaining can help you create a DSL, I thought I would plagiarise some more content that Ian Cooper shared with us last night at the London DNUG.

Ian discussed the simple example of how in some languages it is very easy/readable to do something as simple as creating a DateTime of "20 minutes ago"

Ruby Code :

20.minutes.ago

C# Code:

DateTime.Now.AddMinutes(-20);

To be fair the C# code is not awful, but is less like a DSL and could be made a touch better. So how does C#3.0 help? Extension methods allow us to extend functionality of another type that we may not have defined. So in this example we can migrate to a Ruby style by implementing 2 extension methods.

public static TimeSpan Minutes(this int numberOfMinutes)
{
    return new TimeSpan(0, numberOfMinutes, 0);
}

public static DateTime Ago(this TimeSpan numberOfMinutes)
{
    return DateTime.Now.Subtract(numberOfMinutes);
}

By creating these extension methods we now give int types a new method Minutes() that returns a TimeSpan. We then extend the TimeSpan type to have an Ago() method that returns a DateTime. Very simple stuff that allows us to write code like this

20.Minutes().Ago();

Others have covered this topic before here

Method Chaining to create your DSL

I just attended a London DNUG hosted by Ian Cooper regarding Internal DSLs in C#3.0. It was a very interesting session where Ian covered some very similar content to JP Boodhoo's series of 5 "Demystifying patterns" on DNRTV.com. Firstly Ian Covered simply what a DSL is and how there can be DSL internal to .NET. His examples were RhinoMock (and nMock), LINQ and implementations of a fluent API using strategy patterns and method chaining.

While I have seen people use method chaining before primarily in demos or when I have been using RhinoMocks but I have never heard any guidance on how to construct them. As a quick intro to method chaining and why they constitute a DSL here is an example similar to Ian's.

In this example we create a Meeting type using a MeetingBuilder.

var meeting = new MeetingBuilder()
    .On("C# Internal DSLs")
    .By("Ian Cooper")
    .And("Someone else")
    .At( new Address()
        {
            Street1 = "Skills Matter"
            Street2 = "1 something lane"
            PostCode = "SE1ABC"
        })
    .From(new DateTime(2008, 11, 11, 18, 30))
    .Until(new DateTime(2008, 11, 11, 20, 00))
    .Create();
The general Idea here is that we create something that looks more like English language than standard C# code.

So having shown a simple example of Method chaining, I think it is fair to say that it is quite readable and that non technical people (eg Mum) could probably figure out what I am doing here

Ian Copper and somebody else is presenting "C# Internal DSLs" at Skills Matter on 18:30 11th Nov.

If we analyse the code, first thing I would like to mention is that Ian recommends that all methods from a chaining builder (in this case MeetingBuilder) should return this except the Create() method that returns the final object. Now having considered this, that means that we can deduce that MeetingBuilder has a method On(string). Now considering that On(string) is a method on a Builder it should also return the Builder. Cool. By that rational we can also deduce that By(string), And(string), At(Address), From(DateTime), To(DateTime) and Create() are all methods on MeetingBuilder.

Well that is not so interesting until we consider that if we want to create a really fluent API. For the API to be fluent it should not only be readable, we should provide guidance for consuming it too. Referring back to the example we can see the we probably have mandatory method calls and optional methods. In this case only the And(string) method is optional, all of the others should be mandatory. So how can we drive the consumer/developer to know how to use the API if all methods return this?
The answer : Interfaces.

By setting the return types of the methods to interfaces, we can constrain what the next method can do. We still return this, which then tells us we need to implement a bunch of interfaces. The first method this example requires is On(string) so we need an interface like:

interface IMeetingSubjectBuilder
{
    object On(string);
}

but we cant just return object, we need to return an interface that guides the developer to provide the name of the presenter so we expand our interface definitions

interface IMeetingSubjectBuilder
{
   IMeetingPresenterBuilder On(string subject);
}
interface IMeetingPresenterBuilder
{
    IMeetingPresenterOrAddressBuilder By(string presenter);
}
interface IMeetingPresenterOrAddressBuilder 
{
    IMeetingPresenterOrAddressBuilder And(string otherPresenter);
    IMeetingFromTimeBuilder At(Address address);
}

In the above step we have actually done a few things. Firstly we have swapped out the rubbish return type of object for the IMeetingPresenterBuilder. This will then guide our developers to use the methods on that interface. Next we declare that new interface has the By(string) method. This method returns a third interface. The third interface provides two methods. The first method is the And(string) method that allows us to provide additional presenters. Note that its return type is the interface that defines it, which allows a us to recursively call it to add multiple presenters. The second method provides a way to continue providing Address data and eventually other data.

To jump ahead quickly, here is what the final set of interfaces might look like

interface IMeetingSubjectBuilder
{
   IMeetingPresenterBuilder On(string subject);
}
interface IMeetingPresenterBuilder
{
    IMeetingPresenterOrAddressBuilder By(string presenter);
}
interface IMeetingPresenterOrAddressBuilder 
{
    IMeetingPresenterOrAddressBuilder And(string otherPresenter);
    IMeetingFromTimeBuilder At(Address address);
}
interface IMeetingFromTimeBuilder
{
    IMeetingToTimeBuilder From(DateTime startTime);
}
interface IMeetingToTimeBuilder
{
    IMeetingCreator Until(DateTime endTime);
}
interface IMeetingCreator
{
    Meeting Create();
}

Well this is good progress, so all we have to do now is declare a class that implements these interfaces.

class MeetingBuilder : IMeetingSubjectBuilder, IMeetingPresenterBuilder, IMeetingPresenterOrAddressBuilder, IMeetingFromTimeBuilder, IMeetingToTimeBuilder, IMeetingCreator
{
    public IMeetingPresenterBuilder On(string subject){...}
    public IMeetingPresenterOrAddressBuilder By(string presenter){...}
    public IMeetingPresenterOrAddressBuilder And(string otherPresenter){...}
    public IMeetingFromTimeBuilder At(Address address){...}
    public IMeetingToTimeBuilder From(DateTime startTime){...}
    public IMeetingCreator Until(DateTime endTime){...}
    public Meeting Create() {...}
}

One final problem here is that if we were to use this as per the first example we would find that we could call any of the methods straight from the constructor which could confuse the developer. To better guide the developer we can simply implement all of the interface explicitly except for IMeetingSubjectBuilder.

class MeetingBuilder : IMeetingSubjectBuilder, 
    IMeetingPresenterBuilder, 
    IMeetingPresenterOrAddressBuilder, 
    IMeetingFromTimeBuilder, 
    IMeetingToTimeBuilder, 
    IMeetingCreator
{
    public IMeetingPresenterBuilder On(string subject){...}
    IMeetingPresenterOrAddressBuilder IMeetingPresenterBuilder.By(string presenter){...}
    IMeetingPresenterOrAddressBuilder IMeetingPresenterOrAddressBuilder.And(string otherPresenter){...}
    IMeetingFromTimeBuilder IMeetingPresenterOrAddressBuilder.At(Address address){...}
    IMeetingToTimeBuilder IMeetingFromTimeBuilder.From(DateTime startTime){...}
    IMeetingCreator IMeetingToTimeBuilder.Until(DateTime endTime){...}
    Meeting IMeetingCreator.Create(){...}
}

Now when we create an instance of MeetingBuilder we are guided as to which methods are valid in which order and have a nice fluent API. From the constructor we have the On(string) method available, then from there we have the By(string) and so on.

Creating a Fluent API (and therefore an internal DSL) does require more work and some extra effort at design time but it does make for very nice coding experience for the end developer. For more information see what the godfather has to say here : http://martinfowler.com/dslwip/MethodChaining.html

Wednesday, November 5, 2008

Fail fast

Big Col nails the philosophy of fail fast in his recent blog posts. His first post covers this philosophy at a system level and his second post discusses what you can do in your C#/VB.NET/Java code until fancy Eiffel constructs like spec# make there way in to our languages.

Friday, October 31, 2008

Keeping up with Microsoft and its state of rapid change

If you are anything like me, you feel overwhelmed by rapid advances that are being made just by Microsoft lately. If you were not lucky enough to get to TechEd or the more recent PDC then you will need to get your hands on the content being presented at these events. Beyond the old favourites of DNRTV and Channel9 these sites maybe of interest too:
/web. Microsoft's new homepage for all things web
PDC. The home page for the PDC event that just happened. I have yet to find a web resource of the TechEd content. I was however able to get the content from a friend who did attend (~60GB!). Well worth it if you can get hold of them.

Silverlight progress

There has been some awesome work happening in the silverlight arena lately. The old favourite Health care demo that was a popular demo when WPF premiered is now beeing shown off in silver light here. Far more impressive is the work being done by innoveware to produce a Quake port running on Silverlight. Very cool guys. Looking forward to seeing this in action. At time of posting only a couple of youtube vids were available.

Framework Design Guidelines v2

Brad and Krys are just about to release v2 of their great book Framework Design Guidelines. Here is a link to their recent "pre-release" talk at PDC. I am a big fan of this subject area and find it relevant to all levels of developers. So if you havn't read the original book try to get this new version, or at least watch the video ;-)

Thursday, October 30, 2008

Azure - Microsofts Cloud infrastructure

To compete with Amazon's, Google's etc... cloud systems M$ have announced Azure. See Manuvir Das present Azure on C9 for a technical run down.

Friday, October 3, 2008

Sneaky little WCF error

I was going to drop a post about a WCF issue that had the team scratching their head yesterday afternoon and this morning. However one of the guys on the team spotted this article.

Basically we didn’t validate properly before we threw some enums over the wire, but it would have been nice for WCF to give us an error besides “Connection was closed unexpectedly” which doesn't really lead you to think that a serialization issue is to blame.

Wednesday, October 1, 2008

Progress with Prism

It is good to see the Prism team moving forward not only with the framework/guidance but also with some documentation and clarification of what it is.

I still need to read all the doc and start playing with it. I must admit that the Stock Trader application is very under-whelming. Will have a play before I bag it too much.

This post from Blaine is very handy.

Things for Lee to do:

  • read documentation
  • play with samples

Things for P&P team to do:

  • Pick a name for this product! Is it Prism? CAB? CAB 2.0? CAL? SCSF?

Tuesday, September 30, 2008

Generic Binding in WPF through explicit interfaces and DataTemplates

I have faced a problem recently that required all sorts of different data to be displayed in a single list. Now this probably is not the first time this kind of requirement has surfaced. The requirement was to list entities that could have documents linked to them. These entities don’t really have anything in common, and in fact we don’t even know about these entities as the Document code is independent of anything that consumes it.

Ignoring the requirements for a moment lets just show the problem space. The problem is that we need to display a list of entities of differing types with enough information to identify the entity. Identifying entities is more difficult than just a type + Id/Key pair. Many of the entities are transient or the user may need more information to accurately identify the entity. So we have decided that we need a column for Type, ID/Key, Name and Description/Detail. Further to this the UI designer also wanted space to display comprehensive information about the entity.

So from the information I have from the requirements and the UI guy I decide that the best way to do this is an interface that entities can implement and then they can be displayed on the list.

public interface ILinkedEntity
{
    string Type { get; }
    string Key { get; }
    string Name { get; }
    string Detail { get; }
    string Preview { get; }
}

Then I could display the list like the following

DocumentLinkListExample

Then I thought to myself that exposing Detail and Preview as strings is a stupid Idea because then I would be require presentation logic via string.format in the entity. So I changed the interface to look like this:

public interface ILinkedEntity
{
    string Type { get; }
    string Key { get; }
    string Name { get; }
    object Detail { get; }
    object Preview { get; }
}

Now it is up to the implementer of the interface to return an object that has a DataTemplate ready to be applied to it.

An example of an implementation:

public class Deal : ILinkedEntity
{
    public int DealId { get; set; }
    public string PortfolioNumber { get; set; }
    public string PortfolioGroup { get; set; }
    public int RiskGrade { get; set; }
    public DateTime? DueDate { get; set; }

    #region ILinkedEntity Members
    public string Type
    {
        get { return "Deal"; }
    }

    public string Key
    {
        get { return DealId.ToString(); }
    }

    public string Name
    {
        get { return DealId.ToString(); }
    }

    public object Detail
    {
        get { return DealDescriptionTranslator.Translate(this); }
    }

    public object Preview
    {
        get { return this; }
    }
    #endregion
}

So I create the XAML for the GridView and set the bindings to the correct paths on my ObservableCollection<ILinkedEntity> member.

<ListView x:Name="LinkedEntityList"  ItemsSource="{Binding Path=LinkedEntities}">
  <ListView.Resources>
    <Style TargetType="ListViewItem">
      <Setter Property="ToolTip" Value="{Binding Path=Preview}"/>
    </Style>
  </ListView.Resources>
  <ListView.View>
    <GridView>
      <GridViewColumn Header="Type" DisplayMemberBinding="{Binding Path=Type}"/>
      <GridViewColumn Header="Id/Key" DisplayMemberBinding="{Binding Path=Key}"/>
      <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=Name}"/>
      <GridViewColumn Header="Detail" >
        <GridViewColumn.CellTemplate>
          <DataTemplate>
            <ContentControl 
                Content="{Binding Path=Detail}" 
                ToolTip="{Binding Path=Preview}"
                HorizontalContentAlignment="Stretch"
                HorizontalAlignment="Stretch"
                />
          </DataTemplate>
        </GridViewColumn.CellTemplate>
      </GridViewColumn>
    </GridView>
  </ListView.View>
</ListView>

This all works well except I haven’t provided any DataTemplates for the Objects I return for Detail or Preview members. So I do this as per the UI guy’s specs and put them in a Resource Dictionary that shares scope with the view (app.xaml because Im lazy).

<DataTemplate DataType="{x:Type entities:Deal}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition />
            <RowDefinition />
            <RowDefinition />
        </Grid.RowDefinitions>
        <Label Grid.Column="0" Grid.Row="0" 
       VerticalAlignment="Center">Deal Id :</Label>
        <TextBlock Grid.Column="1" Grid.Row="0" 
           VerticalAlignment="Center" 
           Text="{Binding Path=DealId}" />

        <Label Grid.Column="0" Grid.Row="1" 
       VerticalAlignment="Center">Portfolio :</Label>
        <TextBlock Grid.Column="1" Grid.Row="1" 
           VerticalAlignment="Center" 
           Text="{Binding Path=PortfolioNumber}" />

        <Label Grid.Column="0" Grid.Row="2" 
       VerticalAlignment="Center">Portfolio Group :</Label>
        <TextBlock Grid.Column="1" Grid.Row="2" 
           VerticalAlignment="Center" 
           Text="{Binding Path=PortfolioGroup}" />

        <Label Grid.Column="2" Grid.Row="0" 
       VerticalAlignment="Center">Risk Grade :</Label>
        <TextBlock Grid.Column="3" Grid.Row="0" 
           VerticalAlignment="Center" 
           Text="{Binding Path=RiskGrade}" />

        <Label Grid.Column="2" Grid.Row="1" 
       VerticalAlignment="Center">Due Date:</Label>
        <TextBlock Grid.Column="3" Grid.Row="1" 
           VerticalAlignment="Center" 
           Text="{Binding Path=DueDate}" />

    </Grid>
</DataTemplate>

<DataTemplate DataType="{x:Type entities:DealDescription}">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Path=PortfolioGroup}"/>
        <TextBlock Text="["/>
        <TextBlock Text="{Binding Path=PortfolioNumber}"/>
        <TextBlock Text="]"/>
    </StackPanel>
</DataTemplate>

Right now I’m happy. I am now presenting data as per the requirements and UI design. The only problem is that I am Implementing the Interface implicitly. This creates a lot of noise on some of my entities that have members that are very similar to the ones defined on the interface. For example I have an “DealId” property that is an integer on the Deal object. For a consumer of the object it would be very confusing for them to see both a DealId and a Key property. So I decide to implement the interface explicitly to clean things up.

SHOCK!

My view is now broken! The view presents nothing but blank rows to the user. After a bit of time on the Google-machine I find post on a forum where Josh Smith offers some help. A quick change to the bindings on my XAML to use the interface explicitly :

<ListView x:Name="LinkedEntityList" ItemsSource="{Binding Path=LinkedEntities}">
  <ListView.Resources>
    <Style TargetType="ListViewItem">
      <Setter Property="ToolTip" Value="{Binding Path=Preview}"/>
    </Style>
  </ListView.Resources>
  <ListView.View>
    <!-- this version allows for Explicit interface implementation-->
    <GridView>
      <GridViewColumn Header="Type" 
                      DisplayMemberBinding="{Binding Path=(local:ILinkedEntity.Type)}"/>
      <GridViewColumn Header="Id/Key" 
                      DisplayMemberBinding="{Binding Path=(local:ILinkedEntity.Key)}"/>
      <GridViewColumn Header="Name" 
                      DisplayMemberBinding="{Binding Path=(local:ILinkedEntity.Name)}"/>
      <GridViewColumn Header="Detail" >
        <GridViewColumn.CellTemplate>
          <DataTemplate>
            <ContentControl 
                Content="{Binding Path=(local:ILinkedEntity.Detail)}" 
                ToolTip="{Binding Path=(local:ILinkedEntity.Preview)}"
                HorizontalContentAlignment="Stretch"
                HorizontalAlignment="Stretch"
                />
          </DataTemplate>
        </GridViewColumn.CellTemplate>
      </GridViewColumn>
    </GridView>
  </ListView.View>
</ListView>

Ta-dah! Thanks Josh. All happy now. I have a list that can display things it knows nothing about and hand off any fancy logic to a DataTemplate that should be defined by the UI guy in change of that domain.

Sweet.

Check out full code here

Wednesday, September 10, 2008

Federated identity and Security – Video

Bill Poole recently gave a presentation on Federated Identity at the Perth .Net User Group. His slides are available on his blog post regarding the session. His video available here:

Bill Poole presenting Federated Identity : MP4 Videos (6x~10min.)

At the start of the video the sound is poor due to the distance away from the presenter and the background noise. I move the camera a few minutes in which makes it better.

Friday, August 29, 2008

I have failed you .NET

Recently I have asked to help the IT council at the Bank I work at, identify a technology to help them build small applications quickly. But still allow these applications to be built on a technology that allows for the following criteria:

  1. Has a data store (could be flat file, cloud, DB etc)
  2. Data Access
  3. Single Sign On security
  4. Audit compliance
  5. Logging
  6. Ability to interface to other applications
  7. UI data entry – Forms basic screen workflow that possibly could be configured
  8. Personalization
  9. Widget/Gadget ability (think WebParts or Google gadgets)

Each of these things would then be measured on :

  1. Solve something elegantly
  2. Ease of Development + Pace of development
  3. Ease of support
  4. Robust – Can be made production capable
  5. Ease of which to get development resources
  6. Future proof considerations
  7. Economy/Cost. i.e. A really expensive solution will lose points.

So with my little Microsoft hat on I thought I would throw together a little demo on how .NET does all this with SQL Server (Express if need be). All of that stuff is so damn easy with ASP.NET even though I haven’t touched it in nearly 2 years. They liked my concepts and asked me to present 3 weeks later a little demo. No problems.

So with the distractions of the Olympics, my 1st weekend out of town in 6 months, investing in a new business venture, doing my yearly tax, applying for a UK visa, buying a new house and preparing to move out of my current house; I thought I would be able to knock up a web site to show case how .NET can do all the above. Ok so I was a bit ambitious, however I did produce web site with some functionality. The limited functionality however did everything requested short of Auditing (which I am sure the IT council thinks is the same as Logging). I did present some Auditing options as static screen shots.

It was actually a very reassuring process. I reassured myself that yes I can create a system that can get good test code coverage, with setup/tear down database and was FxCop compliant. That makes me feel all fuzzy. Next thing I was reassured that yes, .NET is a great platform as is so nice to use VS2008 to just get things to work.

What I delivered was :

  1. Single-sign-on via Windows security in ASP.NET (wow! One line of config)
  2. AzMan Authentication. I knocked up an application policy in AzMan manager and used the AzManRoleProvider to enforce it against my site map. I also have an IAuthorize interface which my implementation passed of to AzMan. Seriously, AzMan rocks.
  3. AOP Logging. I’m not a big fan of logging, but as far as logging goes I do like the solution I provided.
  4. Personalization through skins/themes and, well, you guessed it the Personalization framework in ASP.NET. Users could choose their them on the fly and it would be remembered for that user.
  5. Widgets/Gadgets via the WebPart framework. That was great. I never used it before and I had it up and running in minutes.
  6. Sql Express database with build up and tear down scripts of schema and data.
  7. Integration tests for the services to the database.

However I didn’t have time to teach myself WCF and WF in 3 weeks and watch Usain Bolt, Michael Phelps and the Polish women’s volleyball team. So thanks to a recent Readify community event I had seen the Expense report demo application and thought I would use that. So that added Messaging and Workflow to my presentation.

Well I thought it was pretty good what I could showcase given about 30hrs of effort (including power point time). The only problem with .NET and the toys available is, well, it all just works. I only wrote a handful of classes (maybe 20-30 with tests?).

BUT… apparently that wasn’t good enough. Of the other 4 entries, you could imagine if there was LAMP entry or Java entry that was a very compelling argument then sure go with that option. Instead there was SharePoint, Tibco, Jade and a Hosted entry. I know SharePoint is almost the same as ASP.NET but was a slightly different angle to my presentation, but probably coupled with WF or InfoPath could be a nice little application framework. Tibco is more a product offering so requires one more thing to learn, but it also looks like it has some nice stuff. Hosted applications? for a Bank? Surely I have mistaken what they are offering. And finally Jade.

WTF!?! Hands up who knows what Jade is. It is one of those concepts that died like it should have and only really exists as I understand in New Zealand where it is taught at the Uni in Christshurch and has some Major NZ customers which are specks on an international scale. From what I understand it is an OO language and DB rolled into one. From my experience integrating with it for some eCommerce stuff, it performs awfully. And even if I am wrong on all counts, it still fails to meet a bunch of the criteria like:

  • Ease of support – Localized mainly to NZ. Cant really compare it to the massive corporate and community support available for .NET, Java, PHP etc. Even in NZ no one considers it a major player (I know I’m from NZ).
  • Ease of which to get development resources – Where! On Seek.Com.au there were 19 jobs for Jade (11 of which were based in NZ). Compare that to 3200 for .NET and 2500 for Java.
  • Future proof considerations. Jade might not exist in 3 years!
  • Economy/Cost. How much are you going to have to pay for the guys to build and maintain this stuff.
  • Really I must be the worst presenter in the world, or the Jade guy used some black magic. Cause you guessed it, the IT council decided that Jade + Hosted offering were the way to go. Well surly a hosted offereing is going to make single sign on a bit tricky. Nexy, if I really thought Jade was a good language/concept/platform I would have not thrown out the 2 books I had on Jade, or  I may have taken some interest in the awful system I had to integrate to 3 years ago.

    My humble apologies .NET, I have failed you.

    Thursday, August 21, 2008

    Projects – Measuring success and providing boundaries

    Working in the software industry lends itself to a lot of project work. Projects are an interesting beast that seem to be somewhat misunderstood and all too easily fail. Over the past few weeks I have had several discussions regarding all sorts of “projects” and reasons why the forecast is glum on their outcome. These projects are varied as running a sports coaching clinic, change management and of course the software project.

    From my experience with project work, some projects felt good and you always knew they would succeed and others either started shaky or had a honeymoon period that eventually declined into a shaky project. Just to be clear I’m not a PM and this article isn’t so much about how to overcome politics, project buy-in or using Project office. I’m just pointing out some very basic principals that anyone involved in the project should be able to pick up on and should be able to implement on any size project be it professional or getting your son to keep the garden “Clean and Green” (a Stephen Covey analogy).

    First: Set the success criteria. For a project to keep the garden clean, the success criteria might be “Clean and Green”. This is fairly easy to measure. If the grass or plants die or go brown, its not green. If rubbish or leaves start building up then its not clean. Easy.

    If you are on a software project you may have the project success criteria and also some standards to be measured on. For example the development team may require 95% unit test coverage and comments on public types and members [standards]. The project may require an Order approval Use-Case. The measurement of this use case being delivered should be outlined by the business requirements [success criteria].

    Well that seems obvious so what?

    Second: Do not mandate how to implement the project. Step one was to provide a way to measure success, step two is not telling the team how to do it. Provide the boundaries but don’t turn your team in to drones. First it puts too much weight on someone to create all the “How’s”, second it undermines the talent of your team. Generally it is useful to provide an example of some “How’s” and explain why they could be good for meeting the success criteria. We provide an MVP pattern that allows for testing on our WPF client screens. The developer can use that pattern or another pattern if they wish, as long as the “unit test” measurable is met.

    Third: Regular Feedback. A project is fluid. It could have many factors that could change priorities or direction of the project. Like ship at sea, a project needs to be steered. We cant just point the ship in one direction and fix the rudder, we might get blown off course. With constant feedback things that we never would or could have been thought of in advance can be identified. Here are some examples of feedback that have sailed or sunk a project depending on when there were identified:

    • An e-commerce app that works great in one industry (IT Distribution) but failed miserably in another (Bulk Food delivery). The basket scaled to ~30 items. Most usages in the IT industry would place small orders once a day. However restaurants and Hotels tended to restock everything at the start of the week and the 200-300 item basket would blow out to over 1MB in HTML. When the basket tried to refresh on every modification the system became unusable on the target client’s dial up modems.
    • 4 signifcant digits is normally fine for most measurements, unless you are working with GIS data. This was caught early as saved a project from certain failure.
    • Feature creep that came from a “User” that described a “Would have” as a “Must have”. This required an large change in the cost of the project. On further feedback with other users it was identified correctly as out of scope.

    Regular feedback as one method of improving communication sure can help keep the project on track for success. Keeping everyone in contact with each other is also a good way of ensuring people feel like a valued part of the project.

    Fourth : Features, Cost, Time: Pick two. Some projects I have been on a PM hands over some requirements and tells me this must be done by X date. Unless the PM is very experienced, lucky or has some good metrics on build times; this just wont work. One is the function of the other two.

    • pick the features and cost and I can tell you the time it will take
    • pick the features and time and I can tell you the cost
    • pick the time and cost and I can tell you what features can be done

    The fourth point become fairly specific to commercial projects but the first three points can be applied to most “projects”. For me the second point is hard to do. For many it feel natural to control the outcome by controlling the detail. I have to learn to trust my team and let go.

    FxCop 1.36 is out

    I’m a bit of a fan of FxCop. Obviously it is a great static code analysis tool, but it is also great tool for learning. The new version has some bug fixes and support for new language features like anonymous methods and lambda expressions.

    See the release note from the Code analysis and Code Metrics blog.

    Wednesday, August 20, 2008

    .Net user group videos – Perth (Perth DNUG)

    For those that attend the Perth .Net User Group meetings, you may have noticed the video camera recently. I have finally got all of my toys working together to get the files off the camera and on to the web.

    In order of appearance:

    Community Launch topics – July 3rd

    Dave Gardner presenting Web development in Visual Studio 2008: MP4 Video (140MB ~20min)

    Mike Minutillo presenting CSharp 3.0: MP4 Video (154MB ~22min)

    Alistair Waddell LINQ and LINQ-to-SQL Features: MP4 Video (151MB ~22min)

    Mitch Denny presenting Testable Workflows : MP4 Video (109MB ~15min)

    Bill Chestnut Hands On WCF – Jul 10

    Bill Chestnut presenting Hands on WCF : MP4 Video (400MB ~57min)

    Dwayne Read Agile .NET – Aug 7

    Dwayne Read from Strategic Systems presents a discussion on Agile practices in a .Net environment.

    Apologies for the video. The final 10 minutes of the video were cut out. While they were key to the presentation I still thought there was value in releasing the video anyway.

    MP4 Video(388MB ~55min)

    Thursday, August 14, 2008

    Spec# – Contracts in C#

    It looks like the research project Spec# that Microsoft has been working is available to download and play with. Obviously I am behind on the times as this stuff looks like it has been available for some time.

    http://research.microsoft.com/SpecSharp/

    From what I understand from feedback form the ALT.NET event in Seattle and the channel 9 videos (http://channel9.msdn.com/shows/Going+Deep/Expert-to-Expert-Contract-Oriented-Programming-and-Spec/ & http://channel9.msdn.com/forums/Coffeehouse/226756-Using-Spec-in-VS-2005/), Spec# aims to provide us with compile time verification of what constitutes a method or class contract. Just as the shift from VB to .NET meant I had access to a strongly typed world, the shift Spec# looks to offer is further verification on a class or method contract. At a basic level this gives verification on null parameters and some contractual awareness of exceptions.

    I doubt there is any production value in what spec# provides at the moment, but is worth keeping an eye on as the expectation of reliable and durable software keeps increasing.

    Thursday, August 7, 2008

    WPF Styles BasedOn keyless resource

    This post isn't so much to share any new found glory on WPF as it is a note to myself. I can never remember the syntax of basing a WPF style upon the existing default style.

    For example I may want to create a default style for all of my buttons to have a background of "AliceBlue"

    <Style TargetType="Button">
      <Setter value="AliceBlue" property="Background" />
    </Style>

    If I create another style it will not automatically pick up the default styles set above.

    <Style TargetType="Button" x:Key="NewButtonStyle">
      <Setter value="Red" property="Foreground" />
    </Style>

    The fix is to specify the type as the resource key for the BasedOn property.

    <Style TargetType="Button" x:Key="OverrideButtonStyle" BasedOn="{StaticResource {x:Type Button}}">
      <Setter value="Red" property="Foreground" />
    </Style>

    Notice that the middle button wont get the blue background

    <StackPanel>
      <Button>Default</Button>
      <Button Style="{StaticResource NewButtonStyle}">New</Button>
      <Button Style="{StaticResource OverrideButtonStyle}">Override</Button>
    </Stackpanel>

    Nothing new here!

    Tuesday, July 22, 2008

    Fake repository code from SQL

    As I venture into the early stages of life as a Test Driven Developer, I have found it useful to have fake repositories. This allows me to test how the UI will look with out having to wait on fully functional repository/service layer to be in place. I have little SQL pattern I use to generate objects for my fake repo. It may be of use to others, it may not.

    Starting with the end in mind, for this example I basically want a bunch of Orders with their order lines. But if I want a small sample of data say 20 orders and each have only 5 lines that requires me to write a heap of code manually. Instead if we already have the test data agreed on that will populate the final DB or we have an existing database, I can use that data for my fake. Basically I want code to look like this:

    Collection<Order> orders = new Collection<Order>();
    Order order;
    
    order = new Order();
    order.OrderNumber = 1;
    order.DateOrderPlaced = new DateTime(2001, 5, 17);
    order.Lines.Add(new OrderLine(products[1], 50.26M, 4));
    orders.Add(order);
    
    order = new Order();
    order.OrderNumber = 2;
    order.DateOrderPlaced = new DateTime(2001, 5, 17);
    order.Lines.Add(new OrderLine(products[359], 45.12M, 3));
    order.Lines.Add(new OrderLine(products[360], 45.58M, 3));
    orders.Add(order);

    I have already written the code for the products dictionary so lets just focus on how to generate this code.

    Using the AdventureWorks data base in SqlExpress I will get the data to populate this fake data. Now the tricky part here is that we are creating text that for each order has header info (the order object), body info (the order lines) and footer info (adding the order to the orders collection). Some may consider cursors straight off the bat, but I have found what I think to be an easier way. Using the ROW_NUMBER() feature I can determine when to output header, body or footer text. If we partition on the Order Id (in this case the PurchaseOrderId) we will get a Row numbers for each of our orders that start at 1 for each of our orders.

    SELECT
        O.PurchaseOrderID,
        ROW_NUMBER()OVER (PARTITION BY O.PurchaseOrderID ORDER BY ProductId) as Row#,
        OrderDate,
        ProductId,
        UnitPrice,
        OrderQty
    FROM 
        Purchasing.PurchaseOrderHeader H
        INNER JOIN Purchasing.PurchaseOrderDetail O
            ON H.PurchaseOrderId = O.PurchaseOrderId

    From this data we know when to output the header stuff (WHERE RowNumber=1).

    Id Row# OrderDate ProductId UnitPrice OrderQty
    1 1 17 May 2001 1 50.26 4
    2 1 17 May 2001 359 45.12 3
    2 2 17 May 2001 360 45.58 3
    3 1 17 May 2001 530 16.09 550
    4 1 17 May 2001 4 57.03 3
    5 1 31 May 2001 512 37.09 550
    6 1 31 May 2001 513 26.60 550
    7 1 31 May 2001 317 27.06 550
    7 2 31 May 2001 318 33.58 550
    7 3 31 May 2001 319 46.06 550

    But we don’t know when to to output the footer row. So we add a count mechanism.

    SELECT
        O.PurchaseOrderID,
        ROW_NUMBER()OVER (PARTITION BY O.PurchaseOrderID ORDER BY ProductId) as Row#,
        OrderCount.[Count],
        orderdate,
        ProductId,
        UnitPrice,
        OrderQty
    FROM 
        Purchasing.PurchaseOrderHeader H
        INNER JOIN Purchasing.PurchaseOrderDetail O
            ON H.PurchaseOrderId = O.PurchaseOrderId
        INNER JOIN 
        (
            SELECT 
                PurchaseOrderID, 
                Count(*) as [Count] 
            FROM 
                Purchasing.PurchaseOrderDetail T2
            GROUP BY 
                PurchaseOrderID
        ) as OrderCount
            ON O.PurchaseOrderID = OrderCount.PurchaseOrderID 
    Id Row# Count OrderDate ProductId UnitPrice OrderQty
    1 1 1 17 May 2001 1 50.26 4
    2 1 2 17 May 2001 359 45.12 3
    2 2 2 17 May 2001 360 45.58 3
    3 1 1 17 May 2001 530 16.09 550
    4 1 1 17 May 2001 4 57.03 3
    5 1 1 31 May 2001 512 37.09 550
    6 1 1 31 May 2001 513 26.60 550
    7 1 3 31 May 2001 317 27.06 550
    7 2 3 31 May 2001 318 33.58 550
    7 3 3 31 May 2001 319 46.06 550

    Now we can identify the first row per order and the last row. So all we need to do now is write the output code!

    SELECT
        CASE
            --Single line order -->Header + body + footer
            WHEN ROW_NUMBER()OVER (PARTITION BY O.PurchaseOrderID ORDER BY ProductId) = 1 AND OrderCount.[Count] = 1 THEN 
    '
                order = new Order();
                order.OrderNumber = ' + cast(O.PurchaseOrderID as varchar(100)) + ';
                order.DateOrderPlaced = new DateTime(' + cast(Year(orderdate) as varchar(max)) + ', ' + cast(Month(orderdate) as varchar(max)) + ', ' + cast(Day(orderdate) as varchar(max)) + ');
                order.Lines.Add(new OrderLine(products[' + cast(ProductId as varchar(100)) +'], ' + Cast(UnitPrice as varchar(max)) + 'M, ' + cast(orderQty as varchar(100)) +'));
                this.Orders.Add(order);'
            --Header
            WHEN ROW_NUMBER()OVER (PARTITION BY O.PurchaseOrderID ORDER BY ProductId) = 1 THEN 
    '
                order = new Order();
                order.OrderNumber = ' + cast(O.PurchaseOrderID as varchar(100)) + ';
                order.DateOrderPlaced = new DateTime(' + cast(Year(orderdate) as varchar(max)) + ', ' + cast(Month(orderdate) as varchar(max)) + ', ' + cast(Day(orderdate) as varchar(max)) + ');
                order.Lines.Add(new OrderLine(products[' + cast(ProductId as varchar(100)) +'], ' + Cast(UnitPrice as varchar(max)) + 'M, ' + cast(orderQty as varchar(100)) +'));'
            --Footer
            WHEN ROW_NUMBER()OVER (PARTITION BY O.PurchaseOrderID ORDER BY ProductId) = OrderCount.[Count] THEN 
    '            order.Lines.Add(new OrderLine(products[' + cast(ProductId as varchar(100)) +'], ' + Cast(UnitPrice as varchar(max)) + 'M, ' + cast(orderQty as varchar(100)) +'));
                this.Orders.Add(order);'
            --Body
            ELSE
    '            order.Lines.Add(new OrderLine(products[' + cast(ProductId as varchar(100)) +'], ' + Cast(UnitPrice as varchar(max)) + 'M, ' + cast(orderQty as varchar(100)) +'));'
        END
    FROM 
        Purchasing.PurchaseOrderHeader H
        INNER JOIN Purchasing.PurchaseOrderDetail O
            ON H.PurchaseOrderId = O.PurchaseOrderId
        INNER JOIN 
        (
            --Get the line count for each order so we can Identify the footer row.
            SELECT 
                PurchaseOrderID, 
                Count(*) as [Count] 
            FROM 
                Purchasing.PurchaseOrderDetail T2
            GROUP BY 
                PurchaseOrderID
        ) as OrderCount
            ON O.PurchaseOrderID = OrderCount.PurchaseOrderID 

    Friday, July 18, 2008

    Codeplex annoys me

    I thought I might make this public in the hope that 1 of 2 things happens;

    1. either everyone agrees with me
    2. someone shows me the light and tells me how to use the bloody thing.

    For a site that is basically a public code repository, I would think that it would be easy to navigate and provide a simple way to document the application so the end user doesn’t have to down load the whole thing and poke it with a stick to figure out what it is.

    Thursday, July 17, 2008

    How Did You Get Started in Software Development?

    After a post from little brother (well ten minutes younger, he is my twin) regarding his history in computers, I thought I would follow suit.

    Like Rhys, my history started with trying to install games and getting them to either run, or run faster. My first computer exposure was an Amiga 500 at the age of 8 in primary school. We had a computer club with 4 members: A nerdy teacher, my mate, my mate’s older brother and me. We did nothing but learn to format floppy disks and play some flight simulator. We then got an Apple II gs at home which was used for basically printing out pretty thing we made in its word processor and dot matrix color printer. It always was running low on memory which at them time meant nothing to me as I thought all the memory was on the floppy disk. Then we upgraded to a PC. besides the CD drive I couldn't for the life of me figure out why this was an upgrade. Everything seemed worse than my 5+ year old Amiga. Then some gave us an illegal copy of doom and we never looked back to Amigas and apples (till recently). Yes we did end up getting a real copy of Doom by the way. Ironically stealing game software for a 13 year was a real introduction to IT. Zipping files across 8 disks, modifying AUTOEXEC.Bat and CONFIG.SYS files was the real first steps into IT. From there I took some Computer studies classes in High School. We learnt QBasic, HTML, Databases & Gate Logic. It was a really cool intro to programming (instead of word processing or IT admin).

    University – Or lack of.

    From high school I progressed to Uni. I started with CompSci, Physics and Calc. My grades were alright, but I really hated it. The material was kinda fun but didn’t feel like it was applicable to anything. So with some good advise I took up an Diploma in Business Programming. I know it sounds very dorky, but was leagues better than the crap I was being feed at Uni. Once I finished that full time year long course I had written an asp web site running off an Access database in my spare time. Looking back it is actually ok code. www.northsport.co.nz

    Jobs – FTE to contractor

    My first two jobs were post Y2K eCommerce companies. I was lucky to work with a range of talents which taught me my first lessons in corporate life. Conduit was an ASP + SQL Server 7 development shop. This is where I came to grips with (D)HTML, javascript, css, SQL Server, SPs, integration. I followed my mentor Jerome from my first job to my second at his company Neotek. Neotek was an amazing experience and cemented a wide range of skills I had started to pick up at Conduit. Neotek was an early adopter of .Net and had a fantastic product offering which constantly amazed clients with its speed (especially its pricing model).

    My sporting career lead me to Perth. While there I continued to help Neotek with small stand alone projects and picked up a contract building ad hoc websites for Pretzel Logic, a local company. Pretzel was fun as most of the work was 12 week projects that I could dive into get, get done and move on to the next site. From there I moved to contracting for a Bank. This is where I am now. Working for the Bank has proved to be bitter-sweet. We were (very) early adopters of WPF, CAB & WCF which has been awesome to get dirty with new technologies. However big banks move slowly and are full of politics. Bugger.

    So Rhys, there is my spiel.