0

我正在实现一个 WCF 服务(合同 A),该服务最终将调用客户端托管的独立服务(合同 B)。在设计时,当客户端查询我的服务的 WSDL 以构建其代理时,我想包含 Contract B 的 WSDL,以便客户端可以围绕它构建它的服务。不幸的是,我不知道如何将 Contract B 注入到服务发出的 WSDL 中。由于合同是一个接口并且没有 [DataContract] 属性,因此我无法将其添加为已知类型。有没有其他方法可以将合约注入到发出的 WSDL 中?

这是一个例子:

[ServiceContract]
public interface IServerService
{
  [OperationContract]
  void GiveTheServerMyServiceUri(string uri);

  [OperationContract]
  void TellAllClientsSomething(string message);
}

// THIS IS THE INTERFACE I WANT TO INCLUDE IN THE WSDL
[ServiceContract]
public interface IClientService
{
  [OperationContract]
  void ReceiveMessageFromServer(string message);
}

public class ServerService : IServerService
{
  private List<string> knownClients;

  public void GiveTheServerMyServiceUri(string uri)
  { 
    knownClients.Add(uri);
  }

  public void TellAllClientsSomething(string message)
  {
    foreach (string clientUri in knownClients)
    {
      // 1. Create instance of ClientServiceProxy using client's uri
      // 2. Call proxy.ReceiveMessageFromServer(message)
    }
  }
}

起初,这似乎是一个双工合同的教科书示例。但是,对于这个特定的应用程序,由于各种原因,我需要在客户端和服务器之间进行更多的分离,所以我希望只给客户端一个接口来实现(通过 WSDL),让它托管自己的服务,然后告诉我服务的网址。

4

1 回答 1

1

我不认为这是有道理的。除非您的服务正在执行其他服务的服务合同,否则不要这样做。

另一方面,您的服务可以执行其他服务契约,并成为其他服务的客户端。然后,它可以将调用另一个服务合同委托给该另一个服务。


我只是试过这个来确定。我创建了一个新的 WCF 服务库项目。这创建了一个实现 IService1 的 Service1,具有两个操作。我修改了 [ServiceContract] 属性以使用特定的命名空间 ( http://localhost/service1 )。

然后我添加了一个新服务,它为我提供了 Service2,实现了 IService2,只需一个操作 (DoWork)。我更新了 [ServiceContract] 以使用http://localhost/service2/

然后我更新了 Service1 以实现 IService2 和 IService1,并将 IService2.DoWork 委托给 Service2 服务。我还必须添加一个实现 IService2 的新端点,并且我必须指定一个相对地址,这样两者就不会冲突(因为它们在同一个项目中)。结果如下:

using System;

namespace WcfServiceLibrary1
{
    public class Service1 : IService1, IService2
    {
        public string GetData(int value)
        {
            return string.Format("You entered: {0}", value);
        }

        public CompositeType GetDataUsingDataContract(CompositeType composite)
        {
            if (composite.BoolValue)
            {
                composite.StringValue += "Suffix";
            }
            return composite;
        }

        public void DoWork()
        {
            Service2Reference.IService2 svc = null;
            try
            {
                svc = new Service2Reference.Service2Client();
                svc.DoWork();
            }
            finally
            {
                if (svc != null)
                {
                    ((IDisposable)svc).Dispose();
                }
            }
        }
    }
}
于 2009-05-14T23:03:31.787 回答