Developer's Dump

Don’t use “Add Service Reference”!

with 9 comments

The Visual Studio tools have always been crappy at generating code. The result is acceptable if you are a Microsoft representative selling new technology at some fancy seminar, but it is nothing you want to use in a release version of you application. The Visual Studio “Add Service Reference” (WCF) feature makes no exception.

The “Add Service Reference” feature might become handy when you need to connect to some none-.NET services, but in most other cases I sincerely recommend the manual approach. In this article I’m only going to tell you have, if you need more information check Miguel A. Castro’s article “WCF the Manual Way…the Right Way“.

Start by createing a basic class library project and reference the System.ServiceModel. This library is going to be referenced by both the client and the server. Don’t use the WCF templates as they will only make your life harder on the long run.

Add your service interface to the newly created project:

[ServiceContract(Name = "TestService", Namespace = "http://www.company.com/tests")]
public
interface ITestService
{
    
    [OperationContract]
    TestData GetData(TestData data);

}

[DataContract]
public
class TestData
{
   
public TestData(string message)
    {
        Message = message;
    }

    [DataMember]
    public
string Message { get; set; }

   
public
override string ToString()
    {
        return “Some shared override”;
    }
}

Now add a new project to your solution and implement the server the same way you normaly would:

public class TestService: ITestService
{

    #region ITestService Members

    public TestData GetData(TestData data)
    {
        return new TestData(“Hello world! + data.Message);
    }

    #endregion
}

Instead of messing around with the XML configuration file, just configure your host by code:

ServiceHost host = new ServiceHost(typeof(TestService), new Uri[] { new Uri(uri) });
NetTcpBinding
binding = new NetTcpBinding(SecurityMode.Transport);

binding.TransferMode = TransferMode.Streamed;
binding.MaxBufferSize = 65536;

binding.MaxReceivedMessageSize = 104857600;
host.AddServiceEndpoint(typeof(ITestService), binding, “service1″);

host.Open();

As you can see there is not much new to implementing the service, but now it’s time for the client!

Create a new project for the client and reference the class library you first created. Instead of going for the “Add Service Reference” option create your own proxy:

public class TestServiceClient: ITestService
{

    private ITestService service;
    
    public TestServiceClient(Uri uri)
    {
        
// Any channel setup code goes here
   
     EndpointAddress address = new EndpointAddress(uri);
        NetTcpBinding binding = new NetTcpBinding(SecurityMode.Transport);
        binding.TransferMode = TransferMode.Streamed;
        binding.MaxBufferSize = 65536;
        binding.MaxReceivedMessageSize = 104857600;

        ChannelFactory<ITestService> factory = new ChannelFactory<ITestService>(binding, address);
        service = factory.CreateChannel();
    }

    #region ITestService Members

    public TestData GetData(TestData data)
    {
        return service.GetData(data);
    }

    #endregion
}

You can now place useful functions in your data classes and utilize them both on the client and server side. If you are running with .NET 3.5 you can even leave out the Data and Member Contract attributes of the data classes (same as choosing “Reuse types in referenced assemblies” when using thee Add Service Reference feature).

The biggest advantages of building your proxy manually compared to using the Add Service Reference feature is that you can now share classes and have the same client class implement several service interfaces instead of only one.

Written by Tom

January 5, 2009 at 15:06

Posted in WCF

Tagged with , ,

9 Responses

Subscribe to comments with RSS.

  1. [...] This post was prepared with motivation to the points that Miguel A. Castro, NetFXHarmonics and also Developer’s Dump mentioned. So to use WCF service efficiently, I won’t use “Add Service Reference” and [...]

  2. This option only seems practical if you know you’ll only have 1 or 2 clients because those clients have to reference the project with the service contract class. Not really ideal if you have multiple clients and everytime that project gets compiled you have update the clients references.

    suedeuno

    November 18, 2009 at 21:21

  3. HI,
    This post doesn’t give any idea about why not to use add service reference.
    If my webservice is returning arraylist how to handle that in this scenario

    MyWay

    January 21, 2010 at 08:22

  4. What is a good value to use for uri?

    Dan

    July 14, 2011 at 19:01

  5. Heck Add a service and do it right. ;-> WCF rock when done properly.

    Stephen Russell

    September 8, 2011 at 19:07

  6. One of the benefits of using the code generation is setting the aptly name “variables” in a configuration file rather than in code so that you don’t need to recompile and redeploy just to change a configuration setting. I agree with your method of serving and consuming WCF webservices but you are over simplifying things.

    • True. But then again, there is no project I’ve worked in where the app would not have a “custom” config file of its own.

      Tom

      October 2, 2011 at 22:41

  7. I have a question:
    Is this method (writting my own proxy client class instead of making Visual Studio generating code) applicable if the web service I want to use wasn’t made using the recommandation of the 3rd paragraph :
    “Start by createing a basic class library project and reference the System.ServiceModel.”
    I don’t think it’s possible since I only have the web service wsdl url and not a library I can reference in my project.

    roch

    January 6, 2012 at 13:33

    • The method applies when you are responsible for building both the client and the host in a .NET-only environment. In case of an external web service the code generator is the best (and only practical) choise.

      Tom

      January 7, 2012 at 22:50


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.