4 people like it.
    Like the snippet!
  
  Hosting the DLR with IronPython or Ruby
  Definition of the dynamic resolution operators for hosting the DLR. You can either use Ruby or Python, as the module isn't language specific. 
  |   1: 
  2: 
  3: 
  4: 
  5: 
  6: 
  7: 
  8: 
  9: 
 10: 
 11: 
 12: 
 13: 
 14: 
 15: 
 16: 
 17: 
 18: 
 19: 
 20: 
 21: 
 22: 
 23: 
 24: 
 25: 
 26: 
 27: 
 28: 
 29: 
 30: 
 31: 
 32: 
 33: 
 34: 
 35: 
 36: 
 37: 
 38: 
 39: 
 40: 
 41: 
 42: 
 43: 
 44: 
 45: 
 46: 
 47: 
 48: 
 49: 
 50: 
 51: 
 52: 
 53: 
 54: 
 55: 
 56: 
 57: 
 58: 
 59: 
 60: 
 61: 
 62: 
 63: 
 64: 
 65: 
 66: 
 67: 
 68: 
 69: 
 70: 
 71: 
 72: 
 73: 
 74: 
 75: 
 76: 
 77: 
 78: 
 79: 
 80: 
 81: 
 82: 
 83: 
 84: 
 85: 
 86: 
 87: 
 88: 
 89: 
 90: 
 91: 
 92: 
 93: 
 94: 
 95: 
 96: 
 97: 
 98: 
 99: 
100: 
101: 
102: 
103: 
 | module FSharp
    module DlrHosting = 
        open System.Reflection
        open Microsoft.Scripting
        open Microsoft.FSharp.Reflection
        open Microsoft.Scripting.Hosting
       
        let mutable dlrEngine:ScriptEngine = null
                
        let (?) (instance : obj) member' : 'Result = 
            let resultType =  typeof<'Result>
            
            // did we get invoked as a callable member ?
            if FSharpType.IsFunction resultType then
                //the called member from the dlr type should really be a callable!
                let callable = dlrEngine.Operations.GetMember(instance, member')
                if not (dlrEngine.Operations.IsCallable(callable))
                    then failwithf "%s is not callable" member'
                
                let invokeWithNoArguments = fun _ -> [||]
                let invokeWithOneArgument = fun arg -> [|arg|]
                let invokeWithManyArguments = fun args -> FSharpValue.GetTupleFields(args) 
                
                let functionType, _ = FSharpType.GetFunctionElements(resultType)
                let determineArgsFromInvocation = 
                    match functionType with
                    | type' when type' = typeof<unit> -> invokeWithNoArguments
                    | type' when FSharpType.IsTuple type' -> invokeWithManyArguments
                    | _ -> invokeWithOneArgument
                               
                downcast FSharpValue.MakeFunction(resultType, fun argsFromInvocation -> 
                    dlrEngine.Operations.Invoke(callable, determineArgsFromInvocation(argsFromInvocation) ) ) 
            else
                downcast dlrEngine.Operations.GetMember(instance, member')
        
        let (?<-) (instance : obj) member' value = 
            dlrEngine.Operations.SetMember(instance, member', value)
        let createScriptSource (scriptText:string) = 
            dlrEngine.CreateScriptSourceFromString(scriptText, SourceCodeKind.AutoDetect)
        let executeScriptSource (source:ScriptSource) (scope:ScriptScope) = 
            source.Execute(scope)
        let (|>>) (scope : ScriptScope) codeString = 
            let source = createScriptSource(codeString)
            executeScriptSource source scope |> ignore
            scope
        let (|>?) (scope : ScriptScope) codeString = 
            let source = createScriptSource(codeString)
            executeScriptSource source scope
//Example:  I've used the template engine Jinja2 for rendering
// HTML for demonstrating interop.
open System.Collections.Generic
open System
open System.IO
open Microsoft.FSharp.Core
open FSharp.DlrHosting
open IronPython.Hosting
dlrEngine <- Python.CreateEngine()
let sitePackages = Path.Combine( Environment.CurrentDirectory, "Lib", "site-packages")
let sys = dlrEngine.GetSysModule()
sys?path?append(sitePackages)
let convertFunc f =
    FSharpFunc.ToConverter f
let pymodule = createScope() |>> @"
from jinja2 import FileSystemLoader, DictLoader, FunctionLoader
from jinja2 import Environment
import os
def render( data_context, templateLoader, template_name ):
    env = Environment(loader=templateLoader)
    print templateLoader
    template = env.get_template(template_name)        
    return template.render( data_context )     
"
let loadTemplate name = 
   match name with 
    | "result.tmpl" -> "<html><body>{{ greeting }}</body></html>"
    | _ -> "" 
let templateLoader = pymodule?FunctionLoader(convertFunc loadTemplate) |> box
let data = new Dictionary<obj,obj>()
data.["greeting"] <- "hello python from fsharp"
let rendered:string = pymodule?render(data, templateLoader, "result.tmpl") 
printfn "%s" rendered
pymodule |>> "test = 2+2" |> ignore
printfn "%i" pymodule?test |> unbox
printfn "%i" (pymodule |>? "3+4" |> unbox)
        
 | 
Multiple items
module FSharp
--------------------
namespace Microsoft.FSharp
module DlrHosting
from FSharp
namespace System
namespace System.Reflection
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Reflection
val mutable dlrEngine : obj
Full name: FSharp.DlrHosting.dlrEngine
val instance : obj
type obj = System.Object
Full name: Microsoft.FSharp.Core.obj
val member' : string
val resultType : System.Type
val typeof<'T> : System.Type
Full name: Microsoft.FSharp.Core.Operators.typeof
type FSharpType =
  static member GetExceptionFields : exceptionType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
  static member GetFunctionElements : functionType:Type -> Type * Type
  static member GetRecordFields : recordType:Type * ?bindingFlags:BindingFlags -> PropertyInfo []
  static member GetTupleElements : tupleType:Type -> Type []
  static member GetUnionCases : unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo []
  static member IsExceptionRepresentation : exceptionType:Type * ?bindingFlags:BindingFlags -> bool
  static member IsFunction : typ:Type -> bool
  static member IsModule : typ:Type -> bool
  static member IsRecord : typ:Type * ?bindingFlags:BindingFlags -> bool
  static member IsTuple : typ:Type -> bool
  ...
Full name: Microsoft.FSharp.Reflection.FSharpType
static member FSharpType.IsFunction : typ:System.Type -> bool
val callable : obj
val not : value:bool -> bool
Full name: Microsoft.FSharp.Core.Operators.not
val failwithf : format:Printf.StringFormat<'T,'Result> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.failwithf
val invokeWithNoArguments : ('a -> 'b [])
val invokeWithOneArgument : ('a -> 'a [])
val arg : 'a
val invokeWithManyArguments : ('a -> obj [])
val args : 'a
type FSharpValue =
  static member GetExceptionFields : exn:obj * ?bindingFlags:BindingFlags -> obj []
  static member GetRecordField : record:obj * info:PropertyInfo -> obj
  static member GetRecordFields : record:obj * ?bindingFlags:BindingFlags -> obj []
  static member GetTupleField : tuple:obj * index:int -> obj
  static member GetTupleFields : tuple:obj -> obj []
  static member GetUnionFields : value:obj * unionType:Type * ?bindingFlags:BindingFlags -> UnionCaseInfo * obj []
  static member MakeFunction : functionType:Type * implementation:(obj -> obj) -> obj
  static member MakeRecord : recordType:Type * values:obj [] * ?bindingFlags:BindingFlags -> obj
  static member MakeTuple : tupleElements:obj [] * tupleType:Type -> obj
  static member MakeUnion : unionCase:UnionCaseInfo * args:obj [] * ?bindingFlags:BindingFlags -> obj
  ...
Full name: Microsoft.FSharp.Reflection.FSharpValue
static member FSharpValue.GetTupleFields : tuple:obj -> obj []
val functionType : System.Type
static member FSharpType.GetFunctionElements : functionType:System.Type -> System.Type * System.Type
val determineArgsFromInvocation : (obj -> obj [])
val type' : System.Type
type unit = Unit
Full name: Microsoft.FSharp.Core.unit
static member FSharpType.IsTuple : typ:System.Type -> bool
static member FSharpValue.MakeFunction : functionType:System.Type * implementation:(obj -> obj) -> obj
val argsFromInvocation : obj
val member' : 'a
val value : 'b
val createScriptSource : scriptText:string -> 'a
Full name: FSharp.DlrHosting.createScriptSource
val scriptText : string
Multiple items
val string : value:'T -> string
Full name: Microsoft.FSharp.Core.Operators.string
--------------------
type string = System.String
Full name: Microsoft.FSharp.Core.string
val executeScriptSource : source:'a -> scope:'b -> 'c
Full name: FSharp.DlrHosting.executeScriptSource
val source : 'a
val scope : 'b
val scope : 'a
val codeString : string
val source : obj
val ignore : value:'T -> unit
Full name: Microsoft.FSharp.Core.Operators.ignore
namespace System.Collections
namespace System.Collections.Generic
namespace System.IO
namespace Microsoft.FSharp.Core
new : unit -> FSharpFunc<'T,'U>
static member FSharpFunc.ToConverter : func:('T -> 'U) -> System.Converter<'T,'U>
val box : value:'T -> obj
Full name: Microsoft.FSharp.Core.Operators.box
val printfn : format:Printf.TextWriterFormat<'T> -> 'T
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
val unbox : value:obj -> 'T
Full name: Microsoft.FSharp.Core.Operators.unbox
  
  
  More information