我有一个用C#编写的现有项目。我想将其部分业务逻辑移至F#。 MyObjectX是一个运行科学算法的C#类。 要运行MyObjectX,需要实现几个接口,以及通过方法(而不是构造函数)注入的一些依赖项。例如:
public class MyObjectX(): IMathSolver, IBusinessSolver
{
//private fields
private int operationMode;
private ISignalProvider signal;
//Inject dependcy via method
public void SetSignalProvider(ISignalProvider signal)
{
this.signal = signal;
}
//implemention of above interfaces
public double MethodMathSolver()
{
this.signal.GetThreshold();
//...
}
public double Method1BusinessSolver()
{
}
public double Method2MathSolver(IResultProvider provider)
{
var x = provider.GetValueAtTime(0.1);
//...
}
}
所以现在我想在F#中实现MyObjectX。最好的方法是什么,这样我才能在我的代码中尽可能地发挥作用?
使现有的C#MyObjectX在其余C#类之间表现为包装/外观,而F#库的算法在F#模块中实现。
编写一个实现接口的MyObjectX类的F#类,并可能调用其他F#模块。
或者不属于他们。请告知。
将C#的依赖关系传递给F#的最佳方法是什么,如'IResultProvider / ISignalProvider'?我是否需要使用可变变量,这些变量将通过F#中的函数填充依赖项?
请指教。如果你可以分享代码样本,我会很感激。
答案 0 :(得分:5)
我认为你可以在1到2之间做出选择。这些肯定是两种最合理的方法。
我认为选项2可能更好,因为F#实现可以使用最惯用的F#样式(例如将函数作为参数传递)保留在简单的F#模块中。惯用的F#代码并不总是很容易在C#中使用,所以如果你将它包装在一个实现所需C#接口的F#类中,你就会隐藏C#代码中的“F#细节”,这很好。
看看:
F# Component Design Guidelines说明了如何设计F#组件的更多内容,使其易于使用C#。
Interfaces (F#)和F#上的Interfaces page有趣和利润,了解如何在F#中实际编写此类接口实现的更多详细信息。
答案 1 :(得分:3)
FWIW,MyObjectX
的(或多或少)直接翻译是
type MyObjectX() =
let mutable operationMode = 0
let mutable sp : ISignalProvider = Unchecked.defaultof<ISignalProvider>
member this.SetSignalProvider signal = sp <- signal
interface IMathSolver with
member this.MethodMathSolver () =
sp.GetThreshold()
//
0.0
member this.Method2MathSolver provider =
let x = provider.GetValueAtTime 0.1
//
x
interface IBusinessSolver with
member this.Method1BusinessSolver () = 0.0
虽然我不得不猜测几个接口定义。
然而,这并不是特别有用。有关从面向对象转变为功能性思维模式的更多信息,请参阅
答案 2 :(得分:2)
只要接口是在F#项目引用的程序集中定义的,您就可以直接实现MyObjectX
type MyObjectX(signal : ISignalProvider) =
let mutable operationMode : int = 0; // assuming this changes
interface IMathSolver with
member x.GetMethodMathSolver() : double =
signal.GetThreshold()
// ...
member x.MethodBusinessSolver() : double =
...
答案 3 :(得分:1)
查看F#文档。可以简单地创建.NET类和接口,并在语言中使用它们。
如果您希望使用IoC,那么将F#实现注入C#模块应该没有问题,反之亦然。只是玩一玩!
答案 4 :(得分:1)
我说去( 1 )。
这样,您可以让您的生活更容易从其他F#代码引用F#,并且包装应该是无关紧要的。这将增加一个间接级别,让您更改C#接口或F#代码,而不会影响系统的另一面。