Search code examples
.netwcff#type-providers

Reference nested types like a module or namespace


I'm fairly new to F#, and in particular, I'm very new to type providers. I'm working on a project that uses the WsdlService type provider to generate contracts from a WCF service. Here's what my code looks like right now:

type myService = WsdlService<"http://services.mydomain.com/myservices.svc?wsdl">
let myClient = myService.GetIMyService_Basic()

Looks okay so far, other than the odd name generated from the binding name, IMyService_Basic. However, the data contracts from the service are generated in a series of nested classes. That means, I have to do something like this:

let app = new myService.ServiceTypes.My.Long.Namespace.Contracts.ApplicationReference (Name = "MyApplication")
let area = new myService.ServiceTypes.My.Long.Namespace.Contracts.AreaReference (Name = "MyArea", Application = app)
let level = new myService.ServiceTypes.My.Long.Namespace.Contracts.LevelReference (Name = "MyLevel", Area = area)
let node = new myService.ServiceTypes.My.Long.Namespace.Contracts.NodeReference (ExternalKeys = [|"123abc"|], Level = level)
let req = new myService.ServiceTypes.My.Long.Namespace.Contracts.GetChangeSetsByNodeRequest (Node = node)

let res = myClient.GetChangeSets(req).Results
printf "This node has %i total change sets" res.Length;

This is a pretty ugly. I'd much rather do something like use one of the generated types as though it were a module or namespace, like this:

open myService.ServiceTypes.My.Long.Namespace.Contracts // Doesn't work

let app = new ApplicationReference (Name = "MyApplication")
let area = new AreaReference (Name = "MyArea", Application = app)
let level = new LevelReference (Name = "MyLevel", Area = area)
let node = new NodeReference (ExternalKeys = [|"123abc"|], Level = level)
let req = new GetChangeSetsByNodeRequest (Node = node)

let res = myClient.GetChangeSets(req).Results
printf "This node has %i total change sets" res.Length;

Is there any way to achieve this, or at least something more elegant that what I've got so far?


Solution

  • You can use a type abbreviation:

    type AppReference = myService.ServiceTypes.My.Long.Namespace.Contracts.ApplicationReference
    type AreaReference = myService.ServiceTypes.My.Long.Namespace.Contracts.AreaReference
    
    let app = AppReference(Name="MyApplication")
    let area = AreaReference(Name = "MyArea", Application = app)