First of all, I have to say that I know that it is generally not recommended to use F #-specific things when integrating with other .NET languages.
My problem is that I do not understand how to create a link to a service for a service that contains methods that reveal discriminatory unions.
I get basics that are slightly different from this:
type TelephonyProductActivationData = | MobileUseNextIcc | Mobile of decimal | MobileBroadbandUseNextIcc | MobileBroadband of decimal | Fixed | Voip of int16 * int16 static member KnownTypes() = typeof<TelephonyProductActivationData>.GetNestedTypes(BindingFlags.Public ||| BindingFlags.NonPublic) |> Array.filter FSharpType.IsUnion
If you are using F # interactive, first create a type:
type TelephonyProductActivationData = | MobileUseNextIcc of unit | Mobile of decimal<Icc> | MobileBroadbandUseNextIcc of unit | MobileBroadband of decimal<Icc> | Fixed of unit | Voip of BoxNr * int16<BoxPort>;;
And you execute part of the code of known types (slightly modified):
(typeof<TelephonyProductActivationData>.GetNestedTypes(System.Reflection.BindingFlags.Public ||| System.Reflection.BindingFlags.NonPublic) |> Array.filter Microsoft.FSharp.Reflection.FSharpType.IsUnion) |> Array.map (fun x -> x.FullName);;
you will see the following output:
val it : string [] = [|"FSI_0047+TelephonyProductActivationData+Mobile"; "FSI_0047+TelephonyProductActivationData+MobileBroadband"; "FSI_0047+TelephonyProductActivationData+Voip"|]
Note that values ββthat do not have data associated with them have disappeared. This means that when compiling this discriminatory union, no types will be created. By executing this statement in F # interactive:
typeof<TelephonyProductActivationData>.GetProperties() |> Array.map (fun x -> (x.Name));;
we will see what they have become:
val it : string [] = [|"Tag"; "IsVoip"; "Fixed"; "IsFixed"; "IsMobileBroadband"; "MobileBroadbandUseNextIcc"; "IsMobileBroadbandUseNextIcc"; "IsMobile"; "MobileUseNextIcc"; "IsMobileUseNextIcc"|]
As you can see, non-data values ββhave become properties. Now I can show you the real problem. When creating a service link to a service using this method, all I get is:
[System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] [System.SerializableAttribute()] [System.Runtime.Serialization.KnownTypeAttribute(typeof(ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData.Mobile))] [System.Runtime.Serialization.KnownTypeAttribute(typeof(ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData.MobileBroadband))] [System.Runtime.Serialization.KnownTypeAttribute(typeof(ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData.Voip))] public partial class ActivationModelTelephonyProductActivationData : object, System.Runtime.Serialization.IExtensibleDataObject, System.ComponentModel.INotifyPropertyChanged { [System.NonSerializedAttribute()] private System.Runtime.Serialization.ExtensionDataObject extensionDataField; private int _tagField; [global::System.ComponentModel.BrowsableAttribute(false)] public System.Runtime.Serialization.ExtensionDataObject ExtensionData { get { return this.extensionDataField; } set { this.extensionDataField = value; } } [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] public int _tag { get { return this._tagField; } set { if ((this._tagField.Equals(value) != true)) { this._tagField = value; this.RaisePropertyChanged("_tag"); } } } public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged; protected void RaisePropertyChanged(string propertyName) { System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged; if ((propertyChanged != null)) { propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName)); } } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData.Mobile", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] [System.SerializableAttribute()] public partial class Mobile : ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData { private decimal itemField; [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] public decimal item { get { return this.itemField; } set { if ((this.itemField.Equals(value) != true)) { this.itemField = value; this.RaisePropertyChanged("item"); } } } } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData.MobileBroadband", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] [System.SerializableAttribute()] public partial class MobileBroadband : ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData { private decimal itemField; [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] public decimal item { get { return this.itemField; } set { if ((this.itemField.Equals(value) != true)) { this.itemField = value; this.RaisePropertyChanged("item"); } } } } [System.Diagnostics.DebuggerStepThroughAttribute()] [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Runtime.Serialization", "4.0.0.0")] [System.Runtime.Serialization.DataContractAttribute(Name="ActivationModel.TelephonyProductActivationData.Voip", Namespace="http://schemas.datacontract.org/2004/07/Svea.Inri.Data")] [System.SerializableAttribute()] public partial class Voip : ConsoleApplication1.ServiceReference1.ActivationModelTelephonyProductActivationData { private string item1Field; private short item2Field; [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] public string item1 { get { return this.item1Field; } set { if ((object.ReferenceEquals(this.item1Field, value) != true)) { this.item1Field = value; this.RaisePropertyChanged("item1"); } } } [System.Runtime.Serialization.DataMemberAttribute(IsRequired=true)] public short item2 { get { return this.item2Field; } set { if ((this.item2Field.Equals(value) != true)) { this.item2Field = value; this.RaisePropertyChanged("item2"); } } } } }
There are no subclasses for ActivationModelTelephonyProductActivationData (the ActivationModel part is a namespace) that represents values ββthat do not contain any data, and there are no properties in the base class where you can set values ββthat do not contain any data.
My question is finally how to do it. Should I add βunitsβ to all of my discriminatory union values ββthat have no data.