F#中的MEF导出定义重复

时间:2014-05-07 19:58:18

标签: .net f# mef

我有这个相对简单的程序:

open System
open System.ComponentModel.Composition
open System.ComponentModel.Composition.Hosting
open System.Reflection

module Config =
    [<Export("Timer.Delay")>]
    let Delay = TimeSpan.FromSeconds(5.0)

[<EntryPoint>]
let main argv = 
    let catalog = new AssemblyCatalog(Assembly.GetExecutingAssembly())
    let container = new CompositionContainer(catalog)
    let delay = container.GetExportedValue<TimeSpan> "Timer.Delay"

    printfn "Delay: %A" delay

但是在调用container.GetExportedValue<TimeSpan> "Timer.Delay"时出现此错误:

  

找到多个匹配约束的导出:

     

ContractName Timer.Delay

     

RequiredTypeIdentity System.TimeSpan

检查catalog.Parts集合,我看到两个部分,每个部分都有一个ExportDefinitionProgram+Config的第一个,我希望找到的,<StartupCode$Remote>.$Program的一个(注意程序集名称是Remote):

catalog.Parts

main函数包装在module Program中不会改变此行为,也不会将这些模块分成不同的文件。有人知道为什么这个F#程序正在生成第二个导出定义吗?我该如何防止这种情况?

1 个答案:

答案 0 :(得分:2)

稍微摆弄它之后,我想我已经弄明白了。我的猜测是,当F#编译器在上面的属性上看到一个非目标属性时,它实际上会发出两个属性,一个属性属性,一个属性为字段。 ExportAttribute可能应用于属性和字段可能也是相关的。在属性上指定目标似乎可以解决此问题。

这将生成Program+Config部分:

module Config =
    [<property: Export("Timer.Delay")>]
    let Delay = TimeSpan.FromSeconds(5.0)

这将生成<StartupCode$Remote>.$Program部分:

module Config =
    [<field: Export("Timer.Delay")>]
    let Delay = TimeSpan.FromSeconds(5.0)

这两个都可以解决我的问题,但第一个似乎更好,因为它将Export属性绑定到实际模块的成员,而不是绑定到一些编译器生成的代码。