围绕 C# static class 创建 F# 控制台应用程序

Create F# console application around C# static class

我正在尝试围绕基于 C#dll 创建控制台应用程序包装器。我想使用 F# 来做到这一点。我正在使用 UnionArgParser 来解析参数。 F# 以前也接触过,但已经有一段时间了。我将从 node.js 调用控制台应用程序。我查看了 edge.js 但不确定我是否愿意走那条路,因为它似乎更复杂的交互方式,而且似乎有些人在使用它时遇到了问题 - 所以我想到了我正在计划的方式着手去做可能会更健壮和简单。

JavaScript 中,我会做这样的事情(我为我正在处理的一些 signalR 代码做了这样的事情):

var methods = ['method1', 'method2'].reduce((acc, methodName) => {
  acc[methodName] = (...args) => {return [methodName].concat(args)}
  return acc
}, {})

// call method, with a predefined invoker function
invoke(methods.method1('arg1', 2))

所以,对于 F#,我想我会做类似的事情,但所有内容都是强类型的,所以我不确定如何去做。我在想这样的事情:

let invoker methodName args =
  match methodName with
  | "getSomeValues" ->
    toJSON(Invoke(SomeFramework.GlobalFunctions.GetSomeValues, args))
  | "getSomeOtherValues" ->
    toJSON(Invoke(SomeFramework.GlobalFunctions.GetSomeOtherValues, args))
  | _ -> """{"Error": "Incorrect function given."}"""

当然,对于 F#,也许我应该使用更强类型的东西。我什至不确定。我想我希望指出正确的方向,然后我可以自己弄清楚。但现在对我来说这一切看起来有点希腊化。

This blog,可能是我可以使用的东西,但它已经很旧了(2008 年),所以现在可能有更好的方法来处理它。

更新

所以,我将从控制台收到的输入将是这样的。

consoleWrapper.exe --methodname method1 arg1 2

或者我可以做

consoleWrapper.exe --methodname method1 --arg1Value arg1 --arg2Value 2

UnionArgParser 会给我在 union 中定义的原始类型值,我这样称呼:

let arg1 = (results.GetResults <@ arg1Value @>).[0]

所以,我最终只使用 reflection 获取 typeof<MyFramework.MyStaticClass> Type 然后使用 GetMethod 方法和 GetParameters 获取参数方法。然后我将来自控制台应用程序的参数和参数方法结果和 Convert.ChangeType 映射到控制台参数数组。然后我 info.Invoke(null, args) 得到了我的结果。

通常不像 F# 那样强类型化,但它已经在 C# 中类型化了,所以无论哪种方式我都会抛出错误,因为控制台不会是强类型的,没有理由过度构建它。如果它主要是原生的,我认为确保输入更强大是有意义的。

现在,将结果转换为JSON