We have an F# assembly (AssemblyOne
) that references another F# assembly (AssemblyTwo
) in a single Visual Studio 2012 solution. AssemblyTwo
has a reference to a C# DLL (MyCSharpLib
).
A function defined in AssemblyOne
calls a function defined in AssemblyTwo
:
namespace AssemblyOne
[<RequireQualifiedAccess>]
module MyModuleA =
let FetchResult id =
let result = AssemblyTwo.MyModuleC.FetchResult id
result
The function called in AssemblyTwo
calls another function (FetchActualResult()
) in the same assembly that takes a parameter of type MyCSharpType
that belongs to the referenced C# DLL (MyCSharpLib
):
namespace AssemblyTwo
[<RequireQualifiedAccess>]
module MyModuleB =
let FetchActualResult(myCSharpType:MyCSharpLib.MyCSharpType, id:int)
//return a result
[<RequireQualifiedAccess>]
module MyModuleC =
let FetchResult id =
let myCSharpType = new MyCSharpLib.MyCSharpType()
MyModuleB.FetchActualResult(myCSharpType, id)
The solution compiles and builds in Visual Studio; however, when we try to build the project from the command line using MSBuild, the build fails, with the following error in the msbuild.log:
error FS0074: The type referenced through 'MyCSharpLib' is defined in an assembly that is not referenced. You must add a reference to assembly 'MyCSharpLib'.
It appears the type exposed as a parameter from MyCSharpLib
in the FetchActualResult()
function signature in AssemblyTwo
is causing the error.
AssemblyOne
now needs a reference to MyCSharpLib
, even though AssemblyOne
does not directly use anything from MyCSharpLib
.
If we remove the parameter from the function signature the solution builds with no errors.
We have further explored this problem by replicating the code with the following use cases ('->' indicates assembly reference):
AssemblyOne
-> F# AssemblyTwo
-> MyCSharpLib
(C# DLL) (does not build)AssemblyOne
-> F# AssemblyTwo
-> MyFSharpLib
(F# DLL) (does not build)AssemblyOne
-> F# AssemblyTwo
-> C# AssemblyThree
(assembly in same solution) (does not build)AssemblyOne
-> F# AssemblyTwo
-> F# AssemblyThree
(assembly in same solution) (builds)Can this behaviour be explained?
Assuming that there is a typo in your sources as DWright pointed out, I'd say that this error may arise just from the fact that by this code you define a static class MyModuleB with exposed method parameter of an external type MyCsharpType.
This is how the Fsharp code translates to IL (from ILSpy - retranslated to Csharp):
...
public static class MyModuleB
{
public static string FetchActualResult(MyCSharpType myCSharpType, int id)
{
return myCSharpType.Fetch(id);
}
}
If you don't expose the type so that it's statically visible, the error might not appear. This, however, would depend on the implementation of the compiler.
I can imagine, that during compilation of MyModuleA, one configuration of compilation process or version of compiler can try to "touch" MyModuleB, and thus try to reach the unreferenced parameter type, and other might just not touch MyModuleB. It depends.
So the problem seems to me being not in the compilation process, but in the fact, that you expose usage of a type for which you don't reference its assembly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With