3

I have an existing project written in C#. I would like to move part of its business logic to F#. MyObjectX is a C# class that runs scientific algorithms. For MyObjectX to run it needs to implement a couple of interfaces, and some dependencies that are injected via methods (not constructor). Example:

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);
        //...
    }
}

So now I would like to implement MyObjectX in F#. What is the best way to do that so i can be as functional as possible in my code?

  1. Make the existing C# MyObjectX behave as a wrapper/facade between the rest of C# classes and the F# library were the algorithms are implemented in F# modules.

  2. Write a F# class of MyObjectX class that implements the interfaces, and probably call other F# modules.

  3. Or non of them. please advise.

Also what is the best way to pass the dependencies of C# to F# like 'IResultProvider/ISignalProvider'? Do i need to use mutable variables that will get populated with the dependencies via functions in F#?

Please advise. if you can share a code sample i would be thankful.

user1912383
  • 359
  • 2
  • 6
  • 16
  • I don't know F#, but all the CLR languages can reference each other's assemblies, so you should be able "see" all your C# objects from F# and vice-versa. I doubt that answers your question, but hopefully it helps! – BradleyDotNET Mar 20 '14 at 19:26

5 Answers5

6

I think you could choose between 1 and 2. These are certainly the two most reasonable approaches.

I think that the option 2 might be better, because the F# implementation can then stay in simple F# modules using the most idiomatic F# style (such as passing functions around as arguments). The idiomatic F# code is not always easy to use from C#, so if you wrap it in an F# class that implements the required C# interfaces, you are hiding the "F# details" from the C# code, which is good.

Have a look at:

Tomas Petricek
  • 240,744
  • 19
  • 378
  • 553
  • +1 In addition, see [my answer](http://stackoverflow.com/a/22543922/126014) for a stab at translating the `MyObjectX` class to F#. – Mark Seemann Mar 20 '14 at 20:07
  • +1. And I'm by no means an expert, but when I was creating F# library that was supposed to be also consumed on C# side, I went for 2nd option which worked *just perfect* (IMO). – Patryk Ćwiek Mar 21 '14 at 08:30
4

FWIW, the (more or less) direct translation of MyObjectX is

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

although I had to guess at a couple of the interface definitions.

However, this isn't particularly functional. For more information about moving from an object-oriented to a functional mindset, see

Community
  • 1
  • 1
Mark Seemann
  • 225,310
  • 48
  • 427
  • 736
2

So long as the interface is defined in an assembly referenced by the F# project you can just implement MyObjectX directly

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 = 
          ... 
JaredPar
  • 733,204
  • 149
  • 1,241
  • 1,454
1

Take a look at the F# documentation. It is possible to create .NET classes and interfaces trivially and to use those within the language.

If you are looking to use IoC, you should have no problem injecting an F# implementation into a C# module and vice versa. Just have a play!

Chris Ballard
  • 3,771
  • 4
  • 28
  • 40
1

I'd say go for (1).

That way, you'll have make your life easier referencing F# from other F# code, and the wrapper should be trivial to write. That will aslo add a level of indirection, letting you change the C# interface or the F# code without affecting the other side of the system.

Mau
  • 14,234
  • 2
  • 31
  • 52