Question

So here's my situation. I have a class library in C#. It exposes some types like Rectangle. It also exposes some methods for doing algorithmic computation.

It seemed like a good idea to write those algorithmic bits in F#. So I added another F# library project to the solution.

Now here's the issue. In order for the F# project to do algorithmic computations it needs to know about the Rectangle from the C# project. And in order for the C# project to be able to use the F# functions it needs to reference the F# project. So there's the circular reference.

One possible solution is to have a third project where I can define the Rectangle, then reference that project from both F# and C#, and then reference the F# project from C# so I can use the functions.

The issue with this is that then the user of my library would have to not only reference my C# project but also the extra third project (because the use needs to supply the input to the algorithm).

This isn't really acceptable since using F# is just an implementation detail and I don't want it to have any overhead on the way my library is used.

So let's say the Rectangle stays in the C# project. The "interface" to the F# implementation (the method in C# that calls the function in F#) of the algorithm is also in the C# project. How do I link it all up so it works? Are there any other options even?

It seems odd to me to refuse circular references. Tightly bound projects like this one don't really have a directed graph structure.

There's an extra method I'm aware of. The F# project having it's own Rectangle and then do serialization and deserialization on both ends. This is both tedious and contrary to the original idea of using F# to make my code simpler.

Was it helpful?

Solution

It sounds like your real issue is not the dependency itself, but rather concern over the 'packaging' (having to ship three assemblies and requiring linkage to more than one assembly by the end-user.) In these scenarios, you might consider using ILMerge to combine your assemblies into a single DLL. This allows you to use proper decoupling in your projects while still having the convenience of shipping only a single file for your library. This is a very commonly used strategy by vendors of third-party libraries.

There are also various commercial tools available that can perform this process and do other things like obfuscation, license enforcement, etc. but it's unclear whether that's really necessary for your application.

OTHER TIPS

Your real problem here is not really a C#/F# one (although that triggers it), but that an assembly A can't re-export a type from another assembly B without requiring users of A to also take a reference to B.

I would suggest working around this problem by defining Rectangle in the F# assembly, but defining a new Rectangle in the C# assembly as a wrapper type, with an F# Rectangle as a private member. You can then expose the underlying F# algorithms with wrapper functions as well, and provide a constructor for calling code to use directly.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top