2 people like it.

Get the F# module or type of the calling code.

This code snippet enables the retrieval of the entity (Module or F# Type) in which the calling code is executing. This can be used to find the module or type name.

 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: 
//This relies on the "FSharp.PowerPack.Metadata.dll" from the F# powerpack.
//This code will not run inside F# interactive as is requires a compiled F#  
//assembly to retrieve metadata.

#r "FSharp.PowerPack.Metadata.dll"

    open System
    open System.Diagnostics
    open System.Reflection
    open System.Runtime.Serialization

    open Microsoft.FSharp.Metadata
    open Microsoft.FSharp.Reflection

    module FSharpEntity =
        let fromCurrentSite () = 
            let rec getSite (frames:StackFrame list) =
                match frames with
                | [] -> failwith "Unable to get site!"
                | sf::sfl -> 
                    let mb = sf.GetMethod ()
                    if mb.Name <> ".cctor" &&  FSharpType.IsFunction (mb.DeclaringType) = false then mb.DeclaringType
                    else getSite (sfl)

            let st = new StackTrace (1, true)
            let frames = st.GetFrames () |> Array.toList
            let site = getSite (frames)
            FSharpEntity.FromType (site)

//Usage 
    module Test =
        let getCallingEntity () =
            FSharpEntity.fromCurrentSite ()

        
namespace System
namespace System.Diagnostics
namespace System.Reflection
namespace System.Runtime
namespace System.Runtime.Serialization
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Reflection
val fromCurrentSite : unit -> 'a

Full name: Script.FSharpEntity.fromCurrentSite
val getSite : (StackFrame list -> Type)
val frames : StackFrame list
Multiple items
type StackFrame =
  new : unit -> StackFrame + 5 overloads
  member GetFileColumnNumber : unit -> int
  member GetFileLineNumber : unit -> int
  member GetFileName : unit -> string
  member GetILOffset : unit -> int
  member GetMethod : unit -> MethodBase
  member GetNativeOffset : unit -> int
  member ToString : unit -> string
  static val OFFSET_UNKNOWN : int

Full name: System.Diagnostics.StackFrame

--------------------
StackFrame() : unit
StackFrame(fNeedFileInfo: bool) : unit
StackFrame(skipFrames: int) : unit
StackFrame(skipFrames: int, fNeedFileInfo: bool) : unit
StackFrame(fileName: string, lineNumber: int) : unit
StackFrame(fileName: string, lineNumber: int, colNumber: int) : unit
type 'T list = List<'T>

Full name: Microsoft.FSharp.Collections.list<_>
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
val sf : StackFrame
val sfl : StackFrame list
val mb : MethodBase
StackFrame.GetMethod() : MethodBase
property MemberInfo.Name: string
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:Type -> bool
property MemberInfo.DeclaringType: Type
val st : StackTrace
Multiple items
type StackTrace =
  new : unit -> StackTrace + 9 overloads
  member FrameCount : int
  member GetFrame : index:int -> StackFrame
  member GetFrames : unit -> StackFrame[]
  member ToString : unit -> string
  static val METHODS_TO_SKIP : int

Full name: System.Diagnostics.StackTrace

--------------------
StackTrace() : unit
StackTrace(fNeedFileInfo: bool) : unit
StackTrace(skipFrames: int) : unit
StackTrace(e: exn) : unit
StackTrace(frame: StackFrame) : unit
StackTrace(skipFrames: int, fNeedFileInfo: bool) : unit
StackTrace(e: exn, fNeedFileInfo: bool) : unit
StackTrace(e: exn, skipFrames: int) : unit
StackTrace(targetThread: Threading.Thread, needFileInfo: bool) : unit
StackTrace(e: exn, skipFrames: int, fNeedFileInfo: bool) : unit
StackTrace.GetFrames() : StackFrame []
type Array =
  member Clone : unit -> obj
  member CopyTo : array:Array * index:int -> unit + 1 overload
  member GetEnumerator : unit -> IEnumerator
  member GetLength : dimension:int -> int
  member GetLongLength : dimension:int -> int64
  member GetLowerBound : dimension:int -> int
  member GetUpperBound : dimension:int -> int
  member GetValue : [<ParamArray>] indices:int[] -> obj + 7 overloads
  member Initialize : unit -> unit
  member IsFixedSize : bool
  ...

Full name: System.Array
val toList : array:'T [] -> 'T list

Full name: Microsoft.FSharp.Collections.Array.toList
val site : Type
module Test

from Script
val getCallingEntity : unit -> 'a

Full name: Script.Test.getCallingEntity
module FSharpEntity

from Script
Raw view New version

More information

Link:http://fssnip.net/81
Posted:5 years ago
Author:Huw Simpson
Tags: reflection , meta-data