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")
Share and Enjoy:
  • Print
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • RSS
  • StumbleUpon
  • Twitter
Posted by Matt Tagged with: , ,

2 Comments to “Dynamically extending applications using MEF and the new F# CodeDom”

  1. [...] Dynamically extending applications using MEF and the new F# CodeDom (Matt Moloney) [...]

  2. [...] Matt Moloney’s Dynamically extending applications using MEF and the new F# CodeDom. [...]

Leave a Reply

(required)

(required)