如何将F#和C#程序集与ILMerge合并,以便在引用时所有类型都可用?

如何将F#和C#程序集与ILMerge合并,以便在引用时所有类型都可用?,c#,f#,ilmerge,C#,F#,Ilmerge,我有很多F和C项目的解决方案。我的目标是使用ILMerge将它们合并到一个库中。生成的合并dll将放在NuGet包中,并在其他项目中引用。然而,在F#项目中引用合并的dll时,我遇到了一些问题 我遇到的问题是,如果提供给ILMerge的主程序集是F#,那么在F#项目中引用生成的dll只允许访问F#类型。如果选择C#dll作为合并的主程序集,则在F#项目中引用时,合并F#程序集中的扩展方法不可用。另外,当打开封闭的命名空间时,具有AutoOpen属性的模块不再隐式打开 有没有办法合并F#和C#程序

我有很多F和C项目的解决方案。我的目标是使用ILMerge将它们合并到一个库中。生成的合并dll将放在NuGet包中,并在其他项目中引用。然而,在F#项目中引用合并的dll时,我遇到了一些问题

我遇到的问题是,如果提供给ILMerge的主程序集是F#,那么在F#项目中引用生成的dll只允许访问F#类型。如果选择C#dll作为合并的主程序集,则在F#项目中引用时,合并F#程序集中的扩展方法不可用。另外,当打开封闭的命名空间时,具有
AutoOpen
属性的模块不再隐式打开


有没有办法合并F#和C#程序集,以便所有类型(包括扩展方法)都可用?

在我们的代码库中,很大一部分是用F#完成的,其余是用C#完成的。F和C代码都是正面的

我们有一个地狱般的批处理文件来处理合并,我看到的是我们正在使用以下代码进行合并:

echo merging %mergeapp% /keyfile:"%keyfile%" /target:library /attr:"%dstpath%%csharpdll%" /targetplatform:%targetplatform%,%targetlib% /lib:%sllib% /lib:%targetlib% /lib:"%libpath%lib" /out:"%mergedpath%..\%csharpdll%" "%dstpath%%csharpdll%" "%dstpath%%fsharpdll%"
%mergeapp% /keyfile:"%keyfile%" /target:library /attr:"%dstpath%%csharpdll%" /targetplatform:%targetplatform%,%targetlib% /lib:%sllib% /lib:%targetlib% /lib:"%libpath%lib" /out:"%mergedpath%..\%csharpdll%" "%dstpath%%csharpdll%" "%dstpath%%fsharpdll%"
这就是我们想要的。但是,我们不发布任何扩展方法,也不执行任何自动打开。我们发现的是F#编译器中的一个bug,在我们开始在混合中添加模糊处理之前,它要求我们在F#程序集上运行
ildasm
,并删除有问题的代码。另一个问题是F#不正确地支持成员上的受保护修饰符(F#使它们公开),因此我们创建了一个属性,可以挂起要保护的类成员。然后我们编写了一个工具,它使用Cecil将程序集拆开,删除我们的属性,并将对这些成员的访问权限更改为protected()

我不知道AutoOpen,但我必须做一个类似的任务,所以我创建了一个名为“注册者”的类,该类完成了类似的工作:

type FSharpRegistrant() =
    do
        // do whatever I need to get going

然后在C#模块中的静态构造函数中,我编写了一些代码,使用反射来实例化F#注册者以查找类(因为在我的代码库中,C#代码首先构建,根本不知道有F#代码)。这是一个丑陋的代码,有很多错误检查,但它可以工作。

你找到答案了吗?最后我决定不使用ILMerge。所以不幸的是,我没有一个成功合并F和C程序集的答案。