After fiddling with it for a little bit, I think I've figured it out. My guess is that when the F# compiler sees an untargeted attribute on a property like the one above, it actually emits two attributes, one for the property and one for the field. It's probably also relevant that the ExportAttribute
may be applied to properties and fields. Specifying a target on the attribute seems to resolve this issue.
This will generate the Program+Config
part:
module Config =
[<property: Export("Timer.Delay")>]
let Delay = TimeSpan.FromSeconds(5.0)
This will generate the <StartupCode$Remote>.$Program
part:
module Config =
[<field: Export("Timer.Delay")>]
let Delay = TimeSpan.FromSeconds(5.0)
Both of these will solve my problem, but the first one seems better, since it binds the Export
attribute to a member of the actual module, rather than to some compiler-generated code.