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 = "http://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 (4)

  1. sukru says:

    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.

  2. Nicholas Allen says:

    Hi sukru,

    I do recommend giving the assembly qualified name for best compatibility.

  3. Tanveer Badar says:

    Sounds like a fine way to kill interoperabilitiy.

  4. Nicholas Allen says:

    Hi Tanveer,

    This has no interoperability implications as the contract type is not externally visible.