在 《Programming WCF Services》中有这么一段话 "You cannot define WCF contracts that rely on generic type parameters. Generics are specific to .NET, and using them would violate the service-oriented nature of WCF. ",意思是说 "我们不能定义依赖泛型参数的 WCF 契约,因为这违反了面向服务的基本原则……"。


其实我们是可以使用泛型的,只不过在添加宿主和端点时,需要提供封闭构造参数。看下面的例子。

[DataContract]
public class Data<T>
{
[DataMember]
public T X;
}

[ServiceContract]
public interface IMyService<T>
{
[OperationContract]
void Test(Data<T> d);
}

public class MyServie<T> : IMyService<T>
{
public void Test(Data<T> d)
{
Console.WriteLine(d.X);
}
}

public class WcfTest
{
public static void Test()
{
ServiceHost host = new ServiceHost(typeof(MyServie<int>),
new Uri("http://localhost:8080/MyService"));
host.AddServiceEndpoint(typeof(IMyService<int>), new BasicHttpBinding(), "");

ServiceMetadataBehavior metadata = new ServiceMetadataBehavior();
metadata.HttpGetEnabled = true;
host.Description.Behaviors.Add(metadata);

host.Open();
}
}


可以是可以,不过生成的客户端代理类型名字有够怪的。 (当然,我们可以使用 Name 强行指定一个 "好看" 的名字。)

//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行库版本:2.0.50727.42
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------

namespace ConsoleApplication1.localhost
{
[GeneratedCodeAttribute("System.Runtime.Serialization", "3.0.0.0")]
[DataContractAttribute(Namespace = "...")]
[SerializableAttribute()]
public partial class DataOfint : object, IExtensibleDataObject
{
}

[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
[ServiceContractAttribute(ConfigurationName = "ConsoleApplication1.localhost.IMyServiceOf_Int32")]
public interface IMyServiceOf_Int32
{
[OperationContractAttribute(Action = "http://.../IMyServiceOf_Int32/Test", ReplyAction = "...")]
void Test(DataOfint d);
}

[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public interface IMyServiceOf_Int32Channel : IMyServiceOf_Int32, IClientChannel
{
}

[DebuggerStepThroughAttribute()]
[GeneratedCodeAttribute("System.ServiceModel", "3.0.0.0")]
public partial class MyServiceOf_Int32Client : ClientBase<IMyServiceOf_Int32>, IMyServiceOf_Int32
{
public void Test(DataOfint d)
{
base.Channel.Test(d);
}
}
}


 不过,既然是开发 SOA,那么还是遵循标准为好。所以还是建议大家,不要在服务公开接口中使用泛型。至于内部实现该怎么着就怎么着好了。




其实你这样做已经不算是泛型了,因为在宿主提供服务的时候类型已经确定了。




 契约还是可以用泛型来提高代码复用的吗~~~~