tags:

views:

169

answers:

3

Hello there,

I have a WCF Service Library (implemented using NH)

with one of the class say Test, defined as

[DataContract]
public class Test

with two constructors defined as

    internal Test()
    { 

    }

    public Test(int param1, IList<Int32> param2, int param3)
    {
        this.Param1 = param1;
        this.Param2 = param2;
        this.Param3 = param3;
    }

Now, I want my client application to only access the second constructor with params and not the default constructor, which I have tried to hide using internal.

But what actually happening is just opposite. In client application, I am able to see the internal constructor only.

Any thoughts?

+2  A: 

In WCF, when you add a service reference, you get a client proxy - but for the data, only the data (and no behavior) is being deserialized - that's the only thing that's stored and transported in the XML schema.

Your client proxy cannot discover and use any additional constructors, any additional methods on your data contract objects - strictly only the data portion is being transported across the wire.

Also, the standard DataContractSerializer (used by default by WCF) will not even call any constructor when deserializing your data from the message received - it will only allocate a memory chunk large enough for your data and then move the bits into the appropriate memory locations. Any constructor is bypassed (which also explains why the DataContractSerializer does not require a public, parameter-less constructor on its data classes - as does the XmlSerializer).

marc_s
Thank you for taking time to explain :-)
inutan
+1  A: 

By default, WCF follows one of the central tenets of service-orientation:

  • Services share contract, not class

What this means is that when you create a Service Reference in Visual Studio, VS asks the service about the metadata for the service. This contract is expressed in WSDL and XSD, and based on the contract, VS auto-generates corresponding classes. These auto-generated classes constitute your proxy - not the one you defined on the service side. They may look very similar, but they are completely different classes.

Since XSD only expresses structure (and not behavior) the only part of your original data contracts that are carried over from the WSDL to the proxy are the properties that are marked by [DataMember].

The constructor you see is the default constructor of the auto-generated class.

There are ways in which you can share data classes between service and client, but that means that you tightly couple them together, so for most scenarios, this is not recommended.

Mark Seemann
A: 

We share contracts (interfaces and data members) not behavior (methods) with clients when creating proxies from metadata (wsdl).

If you need to share some sort of implementation logic to force how clients interact with your service then you might consider:

  1. Deliver a client-side dll which encapsulates the service proxy and enforces any necessary behavior (initialization, method order, etc).
  2. Validating the data contract values when you receive it to verify they fall within known ranges.

HTH,

Z

Zach Bonham