Neat Samples: MEF in F# Scripts

Jomo Fisher—I posted yesterday about using MEF in F# programs. In the comments Oldrich asked if it was possible to do the same thing in F# scripts. It is indeed possible. It actually looks like a really powerful combination because you can naturally extend your scripts just by adding new #load directives at the top.

There are three pieces to this sample. You have to break your interfaces out into a separate .fsx. Realistically, you’d probably do this in a real compiled F# program too so this isn’t a huge burden on simplicity.

Code Snippet

  1. // MefInterfaces.fsx

  2. // Expose an interface

  3. type ITastyTreat =

  4.     abstract Description : string

Code Snippet

  1. // ChocolateCookie.fsx

  2. #r "System.ComponentModel.Composition"

  3. #load "MefInterfaces.fsx"

  4. namespace ChocolateCookie

  5. open MefInterfaces

  6. open System.ComponentModel.Composition

  7. [<Export(typeof<ITastyTreat>)>]

  8. type ChocolateCookie() =

  9.     interface ITastyTreat with

  10.         member __.Description = "a delicious chocolate cookie"

Code Snippet

  1. // MefHost.fsx

  2. #load "ChocolateCookie.fsx"

  3. open System.Reflection

  4. open System.IO

  5. open System.ComponentModel.Composition

  6. open System.ComponentModel.Composition.Hosting

  7. open MefInterfaces

  8. // Set up MEF

  9. let catalog = new AggregateCatalog()

  10. let assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly())

  11. let container = new CompositionContainer(catalog)

  12. catalog.Catalogs.Add(assemblyCatalog)

  13. // Jar that will contain tasty treats

  14. type TreatJar() =

  15.     [<ImportMany(typeof<ITastyTreat>)>]

  16.     let cookies : seq<ITastyTreat> = null

  17.     member __.EatTreats() =

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

  19. let jar = TreatJar()

  20. container.ComposeParts(jar)

  21. jar.EatTreats()

Thanks Oldrich, for giving me an excuse to try this out.

This posting is provided "AS IS" with no warranties, and confers no rights.