托管实现通用接口的C#泛型类的WCF服务

Mun*_*yal 3 .net wcf

我有一个WCF服务,它公开了一个Generic接口(该服务有一个实现这个接口的泛型类).

然后我尝试在托管控制台应用程序中托管此服务(仅用于测试目的).ThreadStart行导致错误,表示找不到T的类型.

现在我不能通过Main <T>(string [] args)来制作Main泛型,其中T:IComparable <T>因为它说,主要入口点未找到.

我的问题是如何处理这个案子一般?

    // Service Hosting app
    static void Main(string[] args)
    {
       new Thread(new ThreadStart(StartBSTService<T>)).Start();
    }

    static void StartBSTService<T>() where T : IComparable<T>
    {
        string baseAddress = "http://localhost:8080/bst";

        StartAService(typeof(BSTService<T>), baseAddress);
    }
Run Code Online (Sandbox Code Playgroud)

编辑:也添加服务类

  [ServiceContract(Namespace = "http://Microsoft.Samples.GettingStarted")]
  public interface IBSTService<T> where T : IComparable<T> //: ICollection<T>
  {
      [OperationContract]
      void Add(T toAdd);
      // For brevity, not providing all other methods
      // but they are similar IColleciton methods.
  }

public class BSTService<T> : IBSTService<T> where T : IComparable<T>
{
       BinarySearchTree<T> tree = new BinarySearchTree<T>();

       public void Add(T toAdd)
       {
           tree.Add(toAdd);
       }
}
Run Code Online (Sandbox Code Playgroud)

客户端将使用它,就像您将使用任何泛型类型:

    BSTService<string> client = new BSTService<string>; 
    // OR
    BSTService<int> client = new BSTService<int>;
Run Code Online (Sandbox Code Playgroud)

EDIT2: @ asawyer的观点似乎合乎逻辑,Main是泛型类的消费者,所以它应该提供类型,但是我必须为每种类型启动一个新的端点吗?以及如何处理.就像我可以写一个服务包装器,它只暴露一个方法说INIT(Type typeOfBST).客户端调用它来告诉服务他想要启动int或字符串BST.然后客户端调用具有给定类型的实际方法,并将服务通道调用到不同的端点,每个端点都暴露出不同类型的BST.

一般如何处理此类案件?

Lad*_*nka 5

托管服务时,您无法使用开放式泛型.您必须指定具体类型来托管具体服务.如果要为更多通用参数托管服务,则必须为每个参数类型创建一个新主机,并为每个参数公开一个具有唯一地址的端点.托管服务后,它必须能够说出它接受的类型,并在服务描述(WSDL源代码)中描述它们.

WCF在您托管服务的基础上工作,该服务必须能够描述它接受的消息 - 因为它生成服务描述.服务能够根据描述序列化消息.任何平台上的任何客户端都可以使用该描述并向服务发送正确的消息 - 客户端将从描述中了解消息的允许内容,并且因为该服务主机必须使用具体类型 - 而不是T.

您可以通过将基类型指定为泛型参数来克服此问题,但即使在此之后,您的服务必须知道可以使用的所有派生类型而不是基本类型(有多种技术可用于此但它们都不提供随机类型).

编辑:

从技术上讲,您要求的方法是:将类型的名称从客户端发送到主服务.主服务将检查具有该类型的服务是否已存在.如果是,它将把服务的URL发送回客户端.如果不是,它将通过反射创建服务并启动它.它将存储有关新托管服务的信息,并将URL发送回客户端.

另一种变体是预先启动所有服务并具有单个WCF路由服务,该服务将请求路由到正确的服务.

这样的解决方案看起来像维护噩梦,第一个解决方案将具有更差的性能,因为每个操作将需要两个网络呼叫.此外,它通常不具有互操作性,因为您的客户必须预先获得通用合同才能调用此类服务​​.根本不这样做 - 定义有限的使用类集合并使用KnownTypeDataContractResolver使用单一服务.