Search code examples
reflectionf#

Accessing nested items through reflection


Given the following F# code

namespace NS

type A() =
    let agent = MailboxProcessor.Start(fun mbx ->
        let mutable field: int = 0
        
        let f1() = 5

        let rec loop () = async {
            try 
                match! mbx.Receive() with
                | _ ->
                    let f2() = 6
                    ()
            with | _ -> ()
            
            return! loop() }

        loop ())

module B = 
    let a = A()

how to reach 'field', 'f1' and 'f2' through reflection starting from 'a' (or typeof<A>)?


Solution

  • If the code is in a console project, ILSpy reveals how the functions are compiled

    enter image description here

    The code is a simplified version of the real one. With the following code (adapted), we can reach the class corresponding to f1 (others are similar).

    let types = typeof<A>.Assembly.GetTypes()
    let f1 = types |> Array.find (fun t -> t.Name.StartsWith("f1") && t.BaseType.Equals(typeof<unit -> int>))
    

    I agree with Tomas's observations in principle.

    However, in this specific case, being able to do this allowed me to mock the elements and write tests.

    I would beg the readers to refrain from entering into the debate on how tests should only be based on interfaces and the like.

    I am convinced that we should be able to test any kind of code without changing a single comma, and against the view that we need to write code to be "testable". Test code should adapt to code under test, not viceversa