将不相关的合约注入到 WCF 的 MEX 提供商创建的 WSDL 中

发布于 2024-07-19 13:42:08 字数 1211 浏览 8 评论 0原文

我正在实现一个 WCF 服务(合同 A),该服务最终将调用客户端托管的独立服务(合同 B)。 在设计时,当客户端查询我的服务的 WSDL 以构建其代理时,我希望包含合同 B 的 WSDL,以便客户端可以围绕它构建其服务。 不幸的是,我不知道如何将合同 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),让它托管自己的服务,然后只需告诉我该服务的网址即可。

I am implementing a WCF service (Contract A) that will eventually make calls to a standalone service (Contract B) hosted by the client. At design-time when the client queries my service's WSDL to build its proxy, I'd like to include the WSDL for Contract B so the client can build its service around that. Unfortunately, I can't figure out how to inject Contract B into the WSDL emitted by the service. Since the contract is an interface and doesn't have the [DataContract] attribute I can't add it as a known type. Is there any other way to inject a contract into emitted WSDL?

Here's an example:

[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)
    }
  }
}

At first it seems that this is a textbook example of a duplex contract. However, for this particular application, for a variety of reasons, I need a bit more separation between client and server so I was hoping to just give the client an interface to implement (via the WSDL), let it host its own service, then just tell me the service's url.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

顾挽 2024-07-26 13:42:08

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

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


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

然后我添加了一个新服务,它为我提供了 Service2,通过单个操作 (DoWork) 实现了 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();
                }
            }
        }
    }
}

I don't see that this makes sense. Unless your service is implementing the service contract of the other service, then don't do this.

On the other hand, your service can implement the other service contract, and become a client to the other service. It can then delegate calls to the other service contract to that other service.


I just tried this to make sure. I created a new WCF Service library project. This created a Service1 implementing IService1, with two operations. I modified the [ServiceContract] attribute to use a specific namespace (http://localhost/service1).

I then added a new service, which gave me Service2, implementing IService2, with a single operation (DoWork). I updated the [ServiceContract] to use http://localhost/service2/.

I then updated Service1 to implement IService2 as well as IService1, and to delegate IService2.DoWork to the Service2 service. I did also have to add a new endpoint implementing IService2, and I had to specify a relative address, so that the two would not conflict (since they were in the same project). Here's the result:

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();
                }
            }
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文