At work, we are currently using a very very Agile process, which involves 1/4 hourly builds, which was all going brilliantly with a WPF solution and some Mocks and some NUnit test projects. Then we got to the point where we had to start building our WCF service and have the WPF project obtain a new service reference client proxy based on the newly built WCF service project. This is easily achieved using NANT and wiring up dependencies in a NANT script, but we were not in a position where we could actual deploy the WCF Service with every build, due to the fact that we are hosting the WCF service inside a Windows service.
We could have also automated this using InstallUtil.exe to install the service, but this would have added more complexity to an already complex build arrangement within our CI build server AKA “Cruise Control”. We could have done it, but we simply wanted to be able to create a new service reference client proxy. Normally, what one would do would be to add a service reference within Visual Studio, something like the figure shown below:
When you add a service reference using Visual Studio, you typically have to have, the service both deployed and running, and you then point the wizard at the deployed and running service address, which exposes some metadata which allows the wizard to be able to see information about the service. This will then create a bunch of items in Visual Studio, such as the following:
One of these generated files is the service reference client proxy. In this case, it is called “Reference.cs”, which if we examine a small section of it, contains all the DataContract
/ ServiceContract
class definitions.
Which is fine, but as I stated above, what was needed for a continuous build environment (Cruise Control) was the ability to create this service reference client proxy class “Reference.cs” without a deployed service. Mmmm, how could we do that.
Well, luckily, there is a command line tool which can be run as part of a NANT script. This utility is called “svcutil.exe”, and has many options, which you can find using the svcutil.exe /?
switch.
But to help you out, here is what we had to do in order to duplicate the functionality provided by the Visual Studio wizard using just svcutil.exe.
It was a 2 phase operation, the phases are as follows:
Create WSDL from DLLs
You can create a WSDL by using the DLLs themselves, and then you can use the WSDL to create a service reference client proxy class. Here is how we did this.
Switch | Description |
/d: | /d:<directory> Directory to create files in (default: current directory) |
/reference: | /reference:<file path>: Add the specified assembly to the set of assemblies used for resolving type references. |
svcutil /directory:c:\SOMEDIRECTORY "<SERVICE CONTRACT DLL PATH>"
/reference:"<DATACONTRACT DLL PATH>"
NOTE: You may have all your ServiceContract
and DataContract
classes all in one DLL, so in this case you would not need the /reference
: switch, this is only needed to link in additional DLLs.
Use WSDL to Create WPF Client Service Reference Proxy Class
Once we had a WSDL, we could the use this to create a service reference client proxy class. We did this as follows:
Switch | Description |
/d: | /d:<directory> Directory to create files in (default: current directory) |
/l: | Language C# or VB |
/out: | Name of output file |
/noconfig | Do not generate a client layer App.Config file |
/s | /serializable: Generate classes marked with the Serializable Attribute |
/ct | /collectionType: <type>: A fully-qualified or assembly-qualified name of the type to use as a collection data type when code is generated from schemas. |
/ser: | /serializer: Auto - Automatically select the serializer. This tries to use the Data Contract serializer and uses the XmlSerializer if that fails. |
/tcv: | /targetClientVersion:Version35 : Generate code that references functionality in .NET Framework assemblies 3.5 and before. |
/n: | /namespace:<string,string>: A mapping from a WSDL or XML Schema targetNamespace to a CLR namespace. |
/edb | /enableDataBinding: Implement the System.ComponentModel.INotifyPropertyChanged interface on all Data Contract types to enable data binding. |
svcutil
/d:c:\SOMEDIRECTORY
c:\SOMEDIRECTORY\*.wsdl c:\SOMEDIRECTORY\*.xsd
/l:C#
/out:Reference.cs
/noconfig
/s
/ct:System.Collections.Generic.List`1
/ser:Auto
/tcv:Version35
/n:*,<THE NAMESPACE TO USE>
/edb
And that was enough for us to generate a new WPF client service reference proxy class in an automated manner, without the need to have the WCF service deployed and running.
Hope this helps someone out there.