Josh
Josh

Reputation: 598

F# Invoke Function in Module

I'm trying to write an installer for my application that runs (mostly) a bunch of database migrations.

I have a very simple start here, I'm just trying to figure out what invokeMethod should equal.

let RunMigration (fsModule: System.Type) =
    fsModule.GetProperties()
        |> Array.filter (fun property -> property.Name = "run")
        |> Array.map(fun property -> property |> invokeMethod ; "Ran successfully")
        |> String.concat "<br/>"

let RunAllMigrations =
    Assembly
        .GetExecutingAssembly()
        .GetTypes()
        |> Array.filter FSharpType.IsModule
        |> Array.filter (fun fsModule -> fsModule.Namespace = "DredgePos.Migrations")
        |> Array.map RunMigration
        |> String.concat "<br/><hr/>"

At the moment as you can see it is a fairly simple process of

  1. Get all the types in the assembly
  2. Getting all modules in the Migrations namespace.
  3. Then if that module has a function named run, I want to invoke it.

How do I invoke it?

EDIT:

The run method will always be Unit -> Unit

let run () = ()

Upvotes: 1

Views: 241

Answers (1)

Tomas Petricek
Tomas Petricek

Reputation: 243041

In your RunMigration method, you are getting a list of properties of the type - but a function declared as in your example should be compiled as a method. For example, if I have the following module in the current assembly:

module XX = 
  let run () = printfn "hello!"

It should be possible to invoke this if the RunMigration function first finds the run method and then calls the Invoke operation with no arguments (and null as the instance, since this is a static method):

let RunMigration (fsModule: System.Type) =
  let mi = fsModule.GetMethod("run")
  mi.Invoke(null,[||]) |> ignore

This returns obj value, which will be null (as the method returns unit) and so you can typically ignore the result.

Upvotes: 2

Related Questions