我正在实施一个WCF服务(合同A),最终将调用客户端托管的独立服务(合同B)。在设计时,当客户端查询我的服务的WSDL以构建其代理时,我想包含合同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),让它托管自己的服务,然后告诉我服务的网址。
答案 0 :(得分:1)
我不认为这是有道理的。除非您的服务正在实施其他服务的服务合同,否则请不要这样做。
另一方面,您的服务可以实施其他服务合同,并成为其他服务的客户。然后,它可以将对其他服务合同的调用委托给该其他服务。
我只是试着确保这一点。我创建了一个新的WCF服务库项目。这创建了一个实现IService1的Service1,它有两个操作。我修改了[ServiceContract]属性以使用特定的命名空间(http://localhost/service1)。
然后我添加了一个新服务,它通过单个操作(DoWork)为我提供了Service2,实现了IService2。我更新了[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();
}
}
}
}
}