关于我遇到的问题,我已经查看了许多示例(包括Passing Interface in a WCF Service?),但直到现在还没有找到解决方案。我有一个带有以下
的Wcf服务库(.NET 4.0) hello world hello
^ ^
start end
我的项目编译得很好。但是当我尝试从控制台应用程序添加它作为服务引用时,我可以添加它并尝试访问如下方法;
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;
}
}
但我遇到的问题是Wcf服务上的Ping()方法,接口类型是否作为对象channelmanager?像
我尝试将[ServiceKnownType(typeof(TestChannelName))]添加到两个接口但没有运气。
我哪里错了?
答案 0 :(得分:2)
我的答案将分为两部分 - 技术概述为何会发生这种情况 - 以及为何会发生这种情况的哲学思考。
首先从技术角度看看:
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
只能理解具体类型 - 服务参数中由[DataContract]
表示的DataMembers,或者简单类型。任何其他人将被优雅地对待作为对象&#39;而不是编译失败。
哲学部分:
实际上,您正在尝试将方法[ServiceContract]
作为参数传递。服务(在某些DLL中为IL构建逻辑)不会序列化并通过网络 - 不是因为它无法完成 - 因为它不是它们的用途。
在您的示例中IChannelManager
是[ServiceContract]
,您甚至尝试将Ping()
导出为[OperationContract]
。 [ServiceKnownType]
属性无法解决问题。
[ServiceKnownType]
什么时候有用呢?那很好documented,但它的要点是 - 如果运行时的DataMember要保留一些具体的类 - 编译器不能在编译时推断(例如接口,抽象类或基类),那么解串器在尝试反序列化时,将无法猜出应该知道的具体类型。
然后你可以对我说 - 这听起来很公平但我需要将我的逻辑(服务)作为参数传递。我要说的是 - 你需要的是重新设计你的解决方案。也许写下并托管更多服务,并使用相当于Strategy或Delegation模式的服务。
我希望其中一些有帮助。