Mar 212010

Hi folks,

I wrote this little applet to see what the combination of MEF and the F# CodeDom would look like, and for the record it looks really really good.

This combination opens a whole lot of doors. By using the F# CodeDom the plugin source code can brought in from anywhere;

  • A server,
  • A blog,
  • Code generated from a DSL, or even
  • Entered by the user directly.

See below for the implementation.

Basic MEF Code originally from Jomo Fisher

open System.Reflection
open System.IO
open System.ComponentModel.Composition
open System.ComponentModel.Composition.Hosting
open Microsoft.FSharp.Compiler.CodeDom
open System.CodeDom.Compiler
open System.Linq
open System.Collections

open MEF_Interface
// Set up catalog
let catalog = new AggregateCatalog()
let directoryCatalog = new DirectoryCatalog(@"c:\Extensions","*.dll")

let container = new CompositionContainer(catalog)
catalog.Catalogs.Add(directoryCatalog)

// Jar that will contain tasty treats
type TreatJar() =
    [<ImportMany(typeof<ITastyTreat>)>]
    let cookies : seq<ITastyTreat> = null

    member this.EatTreats() =
        cookies |> Seq.iter (fun tt -> printfn "Yum, it was a %s" tt.Description)

let jar = TreatJar()

// Build plugin from string
let fs = new FSharpCodeProvider()
let parameters = new CompilerParameters([|@"C:\Users\moloneymb\Documents\Visual Studio 2010\Projects\MEF\MEF Interface\bin\Debug\MEF_Interface.dll";"System.ComponentModel.Composition.dll";"System.Core.dll"|], "test.dll", true)
parameters.GenerateExecutable <- false
let m = "
namespace ChocolateCookie
open System.ComponentModel.Composition
open MEF_Interface

[<Export(typeof<ITastyTreat>)>]
type ChocolateCookie() =
    interface ITastyTreat with
        member this.Description = \"a delicious chocolate cookie\""

let result = fs.CompileAssemblyFromSource(parameters,m)
for e in result.Errors do System.Console.WriteLine(e.ToString())
for o in result.Output do System.Console.WriteLine(o)

// Copy plug-in to container path
File.Copy(@"C:\Users\moloneymb\Documents\Visual Studio 2010\Projects\MEF\MEF\bin\Debug\test.dll",@"c:\Extensions\test.dll")

// Wait for transfer
System.Console.ReadKey() |> ignore

// Refresh directory catalog to pick up the new plug-in
directoryCatalog.Refresh()

// Run plug-ins
container.ComposeParts(jar)
jar.EatTreats()

// Wait to close
System.Console.ReadKey() |> ignore

// Delete file so we can re-run this program later
File.Delete(@"c:\Extensions\test.dll")
Posted by Matt Tagged with: , ,
Mar 112010

Hi folks,

I have recently been experimenting with combining Reactive X, WPF, and F# and have found the combination to be very palatable. I chose drag and drop as the test case because it is both non trivial and generally deeply stateful. The resulting Rx turns out to be one fifth the code of my original C#, much easier to read and has fewer errors.

Drag and Drop code:

    leftDown
        |> map (fun e1 -> (e1, mouseMove |> takeUntil leftUp |> takeUntil mouseLeave))
        |> filter (fun (e1, e2s) -> e1.Source.Equals(canvas) |> not)
        |> map (fun (e1, e2s) ->
                        let control = e1.Source :?> UIElement
                        let leftTop = (Canvas.GetLeft(control), Canvas.GetTop(control))
                        let pt1 = e1.GetPosition(canvas)
                        e2s |> map (fun e2 ->
                                        let pt2 = e2.GetPosition(canvas)
                                        (control, leftTop, pt2 - pt1)))
        |> mergeAll
        |> subscribe (fun (control, (left,top), delta) -> Canvas.SetLeft(control, left + delta.X); Canvas.SetTop(control, top + delta.Y))

As always, I am interested in feedback.

Cheers,

Matt

Full Code:

Continue reading »

Posted by Matt Tagged with: , ,
Nov 232009
Quick test of the Azure WCF service

Quick test of the Azure WCF service

Azure now has support for input endpoints on Worker Roles! (Azure Tools Nov 2009) This is awesome as it greatly simplifies building WCF services in the cloud. David Aiken has written an excellent Channel 9 post on exactly how to do this (here).

As per usual, I’ve gone ahead and ported the most important components to F# and I have included a short list of some of the difficulties I had while doing so.

Lessons Learned;

1. In Azure, you cannot just specify the input endpoints in code, you have to specify the endpoints in the properties for the role. It will work in the Dev fabric but will not initialize in the cloud. (thanks to Daniel C Wang)

Wrong:

 let baseAddress = Uri("http://kapow.cloudapp.net:8080/service")
 let myServiceHost = new ServiceHost((typeof<GreetingService>), [|baseAddress|])

Right:

using Microsoft.WindowsAzure.SerivceRuntime;

var listenAddress = RoleEnvironment
    .CurrentInstance
    .InstanceEndpoint["<name of your input endpoint >"]
    .IPEndpoint;

string uri = String.Format("http://{0}" ,listenAddress)

2. TryGetValue can return the value in a 2-tuple instead of by ref – this makes it a lot more F# friendly. (from here)

This:

SessionInformation session;
bool exists = sessions.TryGetValue(sessionId, out session)

Becomes this:

let (exists,session) = sessions.TryGetValue(sessionId)

3. KnownTypes – By default, you cannot use a subclass of a data contract class instead of its base class. This took me a while to figure out. (From Programming WCF Services – O’Reilly)

In C#:

[DataContract]
[KnownType(typeof(Custoemr))]
class Contact
{..}

[DataContract]
Class Customer : Contact
{..}

4. You have to take down an Azure deployment in order to change the input endpoints, so no in place upgrades with new endpoints. The Dr. Watson error for this wasn’t very clear.

Things I still can’t figure out;

I am assuming that the ICommunicationObject interface is added by an attribute, I just can’t cast to it. I get an invalid cast error at runtime. I need to do this, so if anyone knows how, please let me know.

In C#:

((ICommunicationObject)client).Abort();

In F#: (from here)

(box client :?> ICommunicationObject).Abort()

The Code:
Continue reading »

Posted by Matt
Nov 132009

This is a proof of concept of an interactive collaborative development environment I built using  F# Interactive. The aim here is to explore different ideas for further development, not so much as to present an alternative to Visual Studio :) Source code here (zip).  ”Make it pink” code (txt), and Space Scene code (txt).

The video demonstrates a server and two clients collaborating on the same machine.

The way it works is that there are two different roles, the server (EchoServer) and the client (EchoClient). The role of the server is to act as repeater between the clients. When one client inputs source code the code is automatically sent to all the other clients. The server stores the code so when a new client joins it can be brought up to speed with all of the other clients.

This has the following advantages;

  • Everyone is on the same page with the latest version of the software
  • All developers work with the very latest source code
  • The source code is continuously integrated in real time
  • ‘Build’ breaks are noticed (and fixed) immediately

There are also a number of disadvantages;

  • Cannot undo certain operations with side effects
  • Code from the network is being downloaded and run on your machine
  • The entire source code is a stored as single string

The reason I am playing with this is prepare for my next move into Domain Specific Modeling tools.

I’ve included the source code below. It is prototype code, so there are probably a few bugs in it, and as always feedback is greatly appreciated.

Continue reading »

Posted by Matt Tagged with: , , ,
Nov 092009

This is a very straightforward port of SQL Azure code from msdn:
Continue reading »

Posted by Matt Tagged with: ,
Nov 092009

I encountered a ton of difficulties while porting code from C# to F#. Fortunately / unfortunately, so have many other people. Thankfully they took the time to write about these problems so my solutions were often only a quick search away. Here is a collection of some of the finds that were able to help me in my endeavors.

I have done my best to attribute sources, and as always feedback is very much appreciated. Also, I will be updating my code viewer as soon as possible to stop it from embedding html smiley faces.

Continue reading »

Posted by Matt Tagged with: , ,
Nov 052009

*Update: Custom WPF Controls in F# is now available on Codeplex at http://wpffsharp.codeplex.com. You can still download the source from my site here. (Works best withVSTS2010 Beta1)

Screen Shot

Screen Shot

It is a translation of SAMS WPF Control Development Unleashed: Building Advanced User Interfaces written by Pavan Podila, and Kevin Hoffman to F#. I picked this book for translation as it covers many advanced topics that other books shy away from. I have been a reader of Pavan Podila’s blog Pixel in Gene for some time, and I have also been waiting for a book dedicated advanced UIs, so when I heard that he was coming out with such a book I knew it was going to be exactly what I needed.

WPF Control Development Unleashed

WPF Control Development

The aim behind this project is to serve as an extensive collection non trivial examples of WPF/F# UI. As I introduce people to F#, one thing I am constantly  asked is; can it do GUI. Now I can say yes, … well sort of. So far I have only translated 3,500 lines of F# code, and I am still not finished.

I’m doing this primarily as a learning experience and as a forcing function. I have already learned a lot about WPF and F#, and I plan on continuously improving the code as I learn more. Other contributions to the project would be very welcome, and if you spot mistakes or know of any better implementations please don’t hesitate to let me know.

I hope that you find this code to be useful to your WPF and F# projects , and happy coding.

-Matt

Read on for a list of known bugs;

Continue reading »

Posted by Matt Tagged with: , , , , ,
Oct 152009

I’ve started playing around with XML in F# interactive and while F# is a joy to work with, the F# interactive sessions have two rather annoying and easily fixed deficiencies.

  1. XML documents are printed out as a sequence of sequences
  2. Printing out XML as text leaves it unformatted, i.e. the whole document is spread out on a single line

To fix this I put together the following function;

#r "System.Xml"

open System.IO
open System.Xml
open System.Text

fsi.AddPrinter(fun (xml : System.Xml.XmlNode) ->
    use ms = new MemoryStream()
    use w = new XmlTextWriter(ms, Encoding.Unicode)
    w.Formatting <- Formatting.Indented
    xml.WriteContentTo(w)
    w.Flush()
    ms.Flush()
    ms.Position <- int64 0
    use sr = new StreamReader(ms)
    sr.ReadToEnd())

My initial expectation was that there would be a library function for nicely formatting XML. If there is and I haven’t found it, or if anyone knows of a better way to do this, please let me know.

Cheers,

Matt

Posted by Matt Tagged with: ,
Jul 192009

This is an experiment in interactive user generated network graph layout. The video demonstrates the ability to specify a domain meta-model (class diagram) and then specify a model in the domain. The layout engine is force directed with a modified gradient decent algorithm for convergence.

Graph & Forces meta model
Meta-model

Tsunami
Tsunami
Posted by Matt Tagged with: , , ,
Jun 032009

This is essentially a 3D browser for Visual Studio Team Foundation Server Work Items. Each of the cubes represents a Work Item, and each of the lines represents a Work Item Link.

Just after adding a large number of nodes

Just after adding a large number of nodes

Before layout

A large network before layout

Continue reading »

Posted by Matt Tagged with: , , , ,