Wcf 服务库接口类型未公开

Wcf Service Library interface type not being exposed

关于我遇到的问题,我看了很多例子(包括Passing Interface in a WCF Service?),但直到现在还没有找到解决办法。我有一个 Wcf 服务库 (.NET 4.0),其中包含以下内容

public class Service : IService
{
    public bool Ping(IChannelManager channelManager)
    {
        return channelManager.Ping();
    }
}

[ServiceContract]
public interface IService
{
    [OperationContract]
    bool Ping(IChannelManager channelManager);
}

[ServiceContract]
[ServiceKnownType(typeof(TestChannelName))]
public interface IChannelManager
{
    [OperationContract]
    bool Ping();
}

[DataContract]
public class TestChannelName : IChannelManager
{
    public bool Ping()
    {
      //perform a ping
      return true;
    }
}

我的项目编译正常。但是当我尝试从控制台应用程序将其添加为服务引用时,我可以很好地添加它并尝试访问如下方法;

using (Test.ServiceClient oClient = new Test.ServiceClient())
{
     oClient.Ping();
}

但我遇到的问题是 Wcf 服务上的 Ping() 方法,接口类型作为对象 channelmanager 出现?喜欢

我尝试将 [ServiceKnownType(typeof(TestChannelName ))] 添加到两个接口,但没有成功。

我哪里错了?

我的回答将分为两部分 - 对为什么会发生这种情况的技术概述 - 以及为什么会发生这种情况的哲学思考。

首先从技术上讲如果你看一下:

http://localhost:8733/Design_Time_Addresses/YourProject/Service1/?singlewsdl

根据您的示例代码创建的 wsdl 文件,您会发现以下内容:

  <xs:element name="Ping">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" name="channelManager" nillable="true" type="xs:anyType"/>
      </xs:sequence>
    </xs:complexType>
  </xs:element>

超过 mex 或如您在上面的 wsdl 中所见。你得到 xs:anytype (实际上是 c# 对象)。这种行为虽然令人沮丧,但在意料之中,Mex 和 WsdlExtractor 只理解具体类型 - DataMembers 在服务参数中由 [DataContract] 表示,或者简单类型。任何其他的都将被优雅地视为 'object' 而不是编译失败。

哲学部分:

实际上,您正在尝试将方法 [ServiceContract] 作为参数传递。服务(在某些 DLL 中将其逻辑构建到 IL)不会序列化并通过网络传递 - 不是因为它无法完成 - 因为这不是它们的目的。

在您的示例中 IChannelManager[ServiceContract],您甚至尝试将 Ping() 导出为 [OperationContract][ServiceKnownType] 属性对此无能为力。

[ServiceKnownType]什么时候有用?好吧,这很好 documented 但它的要点是 - 如果你的 DataMember 在运行时要保存一些具体的 class - 编译器无法在编译时推断(例如接口,抽象 class es 或 base classes) 那么反序列化器将无法猜测在尝试反序列化时它应该 知道 的具体类型。

然后你可能会对我说 - 听起来不错,但我需要将我的逻辑(服务)作为参数传递。对此我要说的是——你需要的是重新设计你的解决方案。也许编写和托管更多服务并使用与 Strategy or Delegation 模式等效的服务。

我希望这对您有所帮助。