How to: Register and Configure a Service Moniker
Before using the Windows Communication Foundation (WCF) service moniker within a COM application with a typed contract, you must register the required attributed types with COM, and configure the COM application and the moniker with the required binding configuration.
Register the required attributed types with COM
Use the ServiceModel Metadata Utility Tool (Svcutil.exe) tool to retrieve the metadata contract from the WCF service. This generates the source code for a WCF client assembly and a client application configuration file.
Ensure that the types in the assembly are marked as
ComVisible
. To do so, add the following attribute to the AssemblyInfo.cs file in your Visual Studio project.[assembly: ComVisible(true)]
Compile the managed WCF client as a strong-named assembly. This requires signing with a cryptographic key pair. For more information, see Signing an Assembly with a Strong Name.
Use the Assembly Registration (Regasm.exe) tool with the
-tlb
option to register the types in the assembly with COM.Use the Global Assembly Cache (Gacutil.exe) tool to add the assembly to the global assembly cache.
Note
Signing the assembly and adding it to the Global Assembly Cache are optional steps, but they can simplify the process of loading the assembly from the correct location at run time.
Configure the COM application and the moniker with the required binding configuration
Place the binding definitions (generated by the ServiceModel Metadata Utility Tool (Svcutil.exe) in the generated client application configuration file) in the client application's configuration file. For example, for a Visual Basic 6.0 executable named CallCenterClient.exe, the configuration should be placed in a file named CallCenterConfig.exe.config within the same directory as the executable. The client application can now use the moniker. Note that the binding configuration is not required if using one of the standard binding types provided by WCF.
The following type is registered.
using System.ServiceModel; [ServiceContract] public interface IMathService { [OperationContract] public int Add(int x, int y); [OperationContract] public int Subtract(int x, int y); }
The application is exposed using a
wsHttpBinding
binding. For the given type and application configuration, the following example moniker strings are used.service4:address=http://localhost/MathService, binding=wsHttpBinding, bindingConfiguration=Binding1
or
service4:address=http://localhost/MathService, binding=wsHttpBinding, bindingConfiguration=Binding1, contract={36ADAD5A-A944-4d5c-9B7C-967E4F00A090}
You can use either of these moniker strings from within a Visual Basic 6.0 application, after adding a reference to the assembly that contains the
IMathService
types, as shown in the following sample code.Dim mathProxy As IMathService Dim result As Integer Set mathProxy = GetObject( _ "service4:address=http://localhost/MathService, _ binding=wsHttpBinding, _ bindingConfiguration=Binding1") result = mathProxy.Add(3, 5)
In this example, the definition for the binding configuration
Binding1
is stored in a suitably named configuration file for the client application, such as vb6appname.exe.config.Note
You can use similar code in a C#, a C++, or any other .NET Language application.
Note
If the moniker is malformed or if the service is unavailable, the call to
GetObject
returns an error of "Invalid Syntax". If you receive this error, make sure the moniker you are using is correct and the service is available.Although this topic focuses on using the service moniker from Visual Basic 6.0 code, you can use a service moniker from other languages. When using a moniker from C++ code the Svcutil.exe generated assembly should be imported with "no_namespace named_guids raw_interfaces_only" as shown in the following code.
#import "ComTestProxy.tlb" no_namespace named_guids
This modifies the imported interface definitions so that all methods return an
HResult
. Any other return values are converted into out parameters. The overall execution of the methods remains the same. This allows you to determine the cause of an exception when calling a method on the proxy. This functionality is only available from C++ code.