torsdag, maj 07, 2009

 

CodeSaga - The version control repository story teller


Just installed CodeSaga on our internal TFS server and I must say I'm impressed!
For a long time I wanted an application like FishEye for our TFS source code repository, but unfortunately, FishEye only works with Perforce, CVS and Subversion...

CodeSaga was quite easy to set up, even though an MSI package would have been nice.
But I guess that is something Torkel might be working on in a near future.
One feature CodeSaga doesn't have yet is the charts of FishEye. But there is a tab already for it in the application, but the page behind it only displays this message:

"Interactive Silverlight charts coming soon to a theather near you!"

Very nice! I'm looking forward to get them into our installation.. :)

Torkel Ödegaard is a consultant at Avega and as far as I understand he created this application as a demo/sample application that shows what you can do with ASP.Net MVC. The application also utilizes some of the nice frameworks I also like very much (Castle Windsor, Rhino Tools) and Boo.

I will definitely look into the code when I get some time for it.
But hey, good for me: I will attend to a talk next tuesday where Torkel is going to speak about ASP.Net MVC. I guess I will ask one or two questions about CodeSaga :)

Etiketter: , , , , , ,


 

How to inject XSL stylesheet reference in WCF service response using a Message encoder

In order to shape up the presentation of the responses from a RESTful WCF web service to clients such as Firefox, you'll need to add an XSL stylesheet reference.
In order to do this, the most straight forward thing to do is to hack into your XML serializable classes and implement this using IXmlSerializable.
Since we want to control this in our service, based on the endpoint URI, this approach was not suitable for our needs.
Also, we don't like cluttering down our serializable entity classes with "presentation logic"/encoding stuff. :)

I posted a question about this in MSDN Forums and got a pretty nice answer from Marco Zhou. He has written a message encoder which injects the XSL stylesheet reference on a lower level which is exactly what we wanted to do.

Thanks Marco!

Etiketter: , , ,


tisdag, maj 05, 2009

 

Castle Windsor 2.0 RTMed

Oh yeah! Castle Windsor 2.0 is RTMed!

I just can't wait 'til we upgrade RemoteX Applications.

Etiketter: , , ,


lördag, april 11, 2009

 

Groovy, RESTful Grails and jQuery - where are we heading in .Net land?

While we heavily focus on Windows Communication Foundation at work my collegue Morten has made some interesting developments with Grails and jQuery lately. Hosting provided by mor.ph, the PaaS he have chosen to use.



For almost one and a half year ago the team I work in decided to move all scripting efforts to PowerShell instead of using other scripting technologies for our system.
(Worth to notice here is that the whole system is built up around the Microsoft .Net platform - with extra salt and pepper.. You got WPF, Team System, PowerShell, etc.).



Now that we got PowerShell we can do quite neat things in scripts that are built upon our classes and system modules written in C#. For example, writing a script which adds an user to the system using our domain model implementation (written in C#) and a REST client is no biggie at all. (the way it should be)

So where are we heading in .Net land to achieve more with less?
I believe we are in a huge need of languages such as PowerShell and IronPython.

Do we need an equivalent for Groovy or are we just fine with IronPython, PowerShell or maybe we should move our attention to the wrist friendly Boo?


What I want is to write RESTful Web Services with very few self-explanatory lines of code, hosted by WCF. Is that possible?
Where is the Groovy in my RESTful .Net land?

Etiketter: , , , , , , , , ,


tisdag, mars 24, 2009

 

A simple bandwidth test based on HTTP, AJAX and jQuery

Recently I had the opportunity to work with my friend Micael on a HTTP broadband testing application. This test will be used as a zero-touch diagnose tool to identify network related issues between users and a video conference system server.

The test was produced for the non-profit organization Infinite Family which involves users located both in the USA and South Africa. The video conference system is located in South Africa and the internet connection to South Africa is provided by a satellite link. Only the hop over the satellite link adds a few hundred milliseconds in response time (ICMP Ping), so it can be really poor conditions for a video link!

The test has equal capabilities as many of the other tests out there. What it does is that it tries to calculate a response time, which of course is not ICMP Ping as one might think, the test only does HTTP and AJAX. Instead, the test uses a HTTP HEAD request to get somewhat a measurement of how long it takes to establish a TCP session and send some data over port 80.
The test does not only measure the response time, it also measure upload and download speeds. For these kind of tests a lot more data is sent back and forth to the HTTP server using (AJAX) HTTP requests.

The whole test consists of one HTML page with references to jQuery and jQuery UI.
This test was the first project in which I could try out jQuery for real. I had some hard time get it working properly on my PCs and the kids' Mac, but now it works in IE, Opera, Firefox and Safari on both Mac OS and Windows.
I must say I really like working with jQuery. To me it's somewhat aligned with the way I use LINQ and extension methods when coding in C#, so it was a piece of cake start coding with this neat Javascript library.
The progress bar used in the test is a pretty simple thing to do with a few DIV elements and a bit of CSS. That was the approach I used in an early version, but I decided to try out jQuery UI as soon as I jumped on the jQuery track.

You can find the test right here.

Etiketter: , , ,


lördag, mars 21, 2009

 

Bacchi Orden Open

Tomorrow is the Bacchi Orden Open taking place in Hornstull, Stockholm.
RemoteX Technologies is sponsoring and I and my collegue Erik will play in the tournament (thanks Pal!).

The Pal asked me quite a while ago for ideas on how we (RemoteX Technologies) could help them out in digitalizing the scorekeeping process during the event. First I thought about putting together a customized version of RemoteX Applications which would help entering scores etc using PDAs. However, the scorekeeping process and the service process (which is what RemoteX Applications primarily supports) did not align very well, so we skipped that idea.
The solution ended up in using their already existing web application (based on the LAMP stack), with some minor adjustments to support Pocket Internet Explorer, Opera for Mobile and such.

QR Code with Face design
Each player plays two so called entries and each entry consists of 4 random games.
Each game on each entry is registered a score and the best score is used in a player ranking algorithm to produce the tournament standings page.
To ease the pain of writing down the score on a piece of paper and THEN enter them into the web application, the solution also involves a free software called i-Nigma which is used to scan QR-codes.
All players get their two entries printed on papers. Each printed entry has four QR-codes, each representing a link to a page on which the score is to be entered by the scorekeeper.
So basically, the scorekeeping process is:

  1. The player plays a game
  2. Calls for the scorekeeper to register the score of the game
  3. The scorekeeper uses a mobile phone equipped with i-Nigma to scan the QR-code of the game
  4. The scorekeeper enters the score in a text field in the web browser on the mobile phone
  5. The player can continue play the remaining games in the entry


AFTER EVENT UPDATE:
Everything worked out eventually, but we came up with a few issues we need to address before the upcoming (bigger) event, Stockholm Open:


We had some really nasty problems during the event, but as my former CEO Ulf Engerby at Qbranch would put it: Success is planned, shit happens!

If you want more information about the event, please visit the website.

Etiketter: , , , ,


måndag, mars 16, 2009

 

How I succeeded to configure Pidgin to work with our Office Communications Server

Since it was a real hassle to figure out these settings I decided to note them here for future references. Since I didn't find this variant of the Pidgin+SIPE+LCS configuration anywhere else, it may be useful for others too.

While talking to others using Pidgin + LCS I noticed the configuration may differ depending on your setup, i.e. internal only or external LCS / SIP server.
At work we use an internal only LCS server which is only listening on its default TCP port (5060).
Below you can see that I need to enter domain + username in the auth* fields. I know others that don't use these fields in their setup, but they do have an externally accessible (over TLS/SSL, port 443) LCS / SIP server.
So be prepared, your result may vary :).


  1. Download Pidgin (v2.5.5 in my case)
  2. Download SIPE (v1.3.3, libsipe.dll, precompiled dist for Windows)
  3. Put libsipe.dll in the plugins directory of Pidgin
  4. Go to Accounts -> Manage Accounts
  5. Choose Add..
  6. Enter the following settings.

    Tab: Basic
    Protocol = Microsoft LCS/OCS
    Username = <your SIP address in Active Directory is your primary e-mail address>
    Password = <your Active Directory password>


    Tab: Advanced
    Use Proxy = Checked
    Proxy Server = <the FQDN of your LCS server, i.e. mylcs.corp.local>
    Use non-standard port = Checked
    Port = 5060
    Connection Type = TCP
    Auth User = <your Active Directory username>
    Auth Domain = <your Active Directory domain name in dotted form, i.e. corp.local>

  7. Click Save and you should see your LCS contacts appearing in the Buddy List of Pidgin


All Done!

torsdag, mars 12, 2009

 

How To Make the Firefox/YouTube Wait Symbol In WPF

Recently I thought about doing one of those trendy animated "hour glasses", the "wait" symbol which appears when that computer of yours is waiting or working on stuff in the background.

So what do I mean by "doing one".. In HTML? with jQuery UI perhaps? No and no.

About 3-4 months ago we started to get WPF into production in our product at work and now we're doing all our new features based on WPF and XAML.
So this animated "hour glass" (or "spinner" which is the word I will use from here) must of course be created in WPF.

I believe that you guys and girls out there who have worked with XAML, since the spec came out in 2006, probably just say "Say hi to XAML, my friend". For me however, I'm quite proud of how easy it was for me to create this animated little thing.

When I brought this up during lunch a couple of days ago I discussed what the least CPU consumtive design would be.
My first design thought I came up with was based on 8 circles with ColorAnimations which would make the circles look like the were rotating.
After a quick discussion with my fellow collegues Morten and Wilhelm I got interested about the idea of using a rotating (using RenderTransform) Canvas instead. This idea worked out very well and here is the result (you must have .Net installed to view it in your browser).

So the XAML required to achieve this is quite simple, here is a summary:

  1. A Canvas is used to distribute the 8 circles on
  2. Each circle has its fixed position and its own transparency (which makes the "tail" effect)
  3. We add a trigger to the FrameworkElement.Loaded event for the Canvas, in which we...
  4. ...add a DoubleAnimation targeting the Angle property of the RotateTransform we also added to the Canvas
  5. We use a ViewBox as the parent of the Canvas which lets us scale the animation to fit in i.e. a TabPage header control (like the tabs in Firefox)


And here is the XAML:

<Viewbox>
<Canvas Width="80" Height="80" Name="canvas">
<Canvas.RenderTransform>
<RotateTransform Angle="0" CenterX="40" CenterY="40" />
</Canvas.RenderTransform>
<Canvas.Triggers>

<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetName="canvas"
Storyboard.TargetProperty="(Canvas.RenderTransform).(RotateTransform.Angle)"
To="360"
Duration="0:0:0.7"
RepeatBehavior="Forever"/>
</Storyboard>

</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Canvas.Triggers>
<Ellipse Canvas.Top="0" Canvas.Left="30" Width="20" Height="20" Fill="#08000000"/>
<Ellipse Canvas.Top="10" Canvas.Left="50" Width="20" Height="20" Fill="#15000000"/>

<Ellipse Canvas.Top="30" Canvas.Left="60" Width="20" Height="20" Fill="#38000000"/>
<Ellipse Canvas.Top="50" Canvas.Left="50" Width="20" Height="20" Fill="#55000000"/>
<Ellipse Canvas.Top="60" Canvas.Left="30" Width="20" Height="20" Fill="#88000000"/>
<Ellipse Canvas.Top="50" Canvas.Left="10" Width="20" Height="20" Fill="#aa000000"/>
<Ellipse Canvas.Top="30" Canvas.Left="0" Width="20" Height="20" Fill="#cc000000"/>
<Ellipse Canvas.Top="10" Canvas.Left="10" Width="20" Height="20" Fill="#ff000000"/>

</Canvas>
</Viewbox>


Pretty easy, or what do you think?

Etiketter: , ,


 

A fluent interface and the Builder pattern

My former collegue Thomas Lundström blogged about fluent interfaces quite a while ago, which he followed up in a comment to Johan Lindfors' post "A small DSL to order coffee" (in Swedish).

The blog post and its comments discusses two different approaches to fluent interfaces. The first approach is based on getters which mutates the instance when they are called. Some people think this is a very bad design - getters should not mutate the instance!
I agree on that. I strongly believe that a get operation should be idempotent and not mutate the object instance. This for the same reason a HTTP GET request should not mutate a resource and a HTTP POST/PUT should mutate a collection/the resource.
(That's why I prefer RESTful web services more than SOAP over HTTP, but that's a totally different blog post. :)

The second approach is the one that Thomas points out. It's the classical Builder Pattern where you have a totally separate class which is used to build object instances. It differentiates itself among the creational OOD design patterns by targeting primarily mutable objects. It's like a bunch of Factory methods which is used like a Factory, but instead of having thousands of different methods in one Factory (overloads for example), the Builder is used in several calls to create/configure the final object instance.

An approach which was recently used at work is a mix of the two approaches mentioned above. Instead of having a separate builder we have builder methods on the object instance itself, either directly or via extension methods. Separate from the builder methods we got some Factory Methods. These are the starting point to create a basic instance. The builder methods are then used to further shape the object instance to our needs.

Approach #1 - getters which creates/mutate the object instace:

Coffee myLatte = Coffee.OrderLatte.Double.FatFree.Vanilla;


Approach #2 - a separate builder

Coffee myLatte = CoffeeBuilder.Latte().Double().FatFree().Vanilla().Build();


Our approach - a mix of factory methods and builder methods on the object instance itself

Coffee myLatte = Coffee.Latte().Double().FatFree().Vanilla();


So what's the pros and cons with the last two approaches?
I guess they are quite similar, but here is some pros:
- The separate builder seems a bit more aligned with the Separation Of Concerns principle
- The built-in builder methods via extension methods provides a lightweight class structure, even for classes in a third-party class library, such as the BCL.

(Please post a comment if you can think of more pros and cons or if you just totally disagree with me :)

So of course, the $10.000 question answer is... It depends on your context!
Anyhow, here is a sample how we tend to use this mix of Factory Methods and Builder methods at work.

The following code is used to build construct the collection of DataGridViewColumns used in a Windows Forms DataGridView control.
The CreateColumns() method is used to create an enumeration of the columns to use and TextColumn() is a sample Factory Method.


protected override IEnumerable CreateColumns()
{
yield return TextColumn()
.For( WorkOrderPresenter.Properties.Title )
.WeightedWidth( 100 );

yield return TextColumn()
.For( WorkOrderPresenter.Properties.Description )
.WeightedWidth( 200 );

yield return ComboBoxColumn( _activityBindingSource )
.For( WorkOrderPresenter.Properties.Activity )
.WeightedWidth( 100 )
.Width( 90, 130 );
....
}

///
/// Creates a textbox column with default behavior.
///

protected virtual DataGridViewTextBoxColumn TextColumn()
{
return new DataGridViewTextBoxColumn().WrapContents().WithDefaultBehavior();
}


The methods For(), WeightedWidth(), Width(), WrapContents() and WithDefaultBehavior() are Builder (extension) methods on DataGridViewColumn.

Etiketter: , , , , ,


Prenumerera på Inlägg [Atom]