Jaa


Referring to Generic Interfaces in Contracts

How do I write a contract type that has a generic parameter in a service configuration file?

A contract reference is part of the template for defining a service endpoint through configuration:

 <endpoint address=”...” binding=”...” contract=”...” />

Now, you need to fill in the contract value based on the full name of the service contract type. This is the same regardless of whether the service contract type has generic type parameters. The presence of type parameters makes writing the type name more complicated because each of the type parameters needs to be written out using its assembly qualified name.

For example, let’s try writing a generically typed service and start plugging in different type parameters.

 [ServiceContract]
interface IEchoService<T>
{
    [OperationContract]
    T Echo(T value);
}

class EchoService<T> : IEchoService<T>
{
    public T Echo(T value)
    {
        return value;
    }
}

public class Class1
{
    private static void Main(string[] args)
    {
        Test<string>("hello world");
        Test<Tuple<double, double>>(new Tuple<double, double>(1.0, 1.5));
    }

    private static void Test<T>(T value)
    {
        string address = "https://localhost:8000/";
        Binding binding = new BasicHttpBinding();
        ServiceHost host = new ServiceHost(typeof(EchoService<T>));
        host.AddServiceEndpoint(typeof(IEchoService<T>), binding, address);
        host.Open();
        ChannelFactory<IEchoService<T>> factory = new ChannelFactory<IEchoService<T>>(binding);
        IEchoService<T> proxy = factory.CreateChannel(new EndpointAddress(address));
        Console.WriteLine("echoed {0}", proxy.Echo(value));
        factory.Close();
        host.Close();
    }
}

What would the service contract type names look like?

When you plug in string as the type parameter it would look like:

EchoService`1[[System.String, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

When you plug in Tuple, which itself has generic type parameters, then continue applying the replacement rule:

EchoService`1[[System.Tuple`2[[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Double, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]]

Comments

  • Anonymous
    April 04, 2010
    Do you need the version part: , mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 usually EchoService`1[[System.String]] works with reflection calls.

  • Anonymous
    April 05, 2010
    Hi sukru, I do recommend giving the assembly qualified name for best compatibility.

  • Anonymous
    April 05, 2010
    The comment has been removed

  • Anonymous
    April 06, 2010
    Hi Tanveer, This has no interoperability implications as the contract type is not externally visible.