首先,这不是 IEnumerable<T> as return type for WCF methods 的副本,我想我明白 WCF 架构只允许传输可以填充到消息中的具体类型。
其次,我们的设置不是一般服务,而是通过 C# + WCF + NetTcpBinding 连接一组专有应用程序+ Protobuf (仅) 因此我们可能有更多的空间来使用一些需要更具约束力的中立的技巧。
第三,提出不同的 RPC 或消息传递框架既不是我的职责,也不是这个问题的职责。
“IEnumerable 语义”,对于这个问题的目的,是:
- 返回的序列可以是任意大的——因此不可能将该序列转换为
List
或类似的。 - 事先不知道有多少元素会被退回
- 调用者只需使用
foreach
即可。
在本地程序集中,C# 接口(interface)看起来像这样:
interface IStuffProvider {
IEnumerable<Stuff> GetItems(); // may open large file or access database
}
您不能将其直接映射到 WCF 服务。可能达到相同效果的东西看起来像:
[ServiceContract(SessionMode = SessionMode.Required)]
interface IStuffService {
[OperationContract]
void Reset(); // may open large file or access database
[OperationContract]
List<Stuff> GetNext(); // return next batch of items (empty list if no more available)
}
当然,使用 IStuffService
将比 IStuffProvider
更容易出错,并且添加到混合中,而不是许多使用场景涉及同时使用服务和客户端机,因此对于“用户代码”而言,意识到涉及“网络”并不是特别重要,用户代码只对简单的界面感兴趣。
一个选项当然是有一个客户端接口(interface)包装器实现,它公开 IStuffProvider
并在内部转发到并使用 IStuffService
。
但是,似乎确实希望不必必须维护两个接口(interface),一个用于用户代码,一个仅用于 WCF 通信,尤其是当这些应用程序无论如何都是紧密耦合的时,因此额外的抽象似乎只是开销。
WCF 有哪些选择?
请注意,在阅读完之后,Streamed Binding似乎是一个糟糕的解决方案,因为我仍然在客户端需要一个包装器并且服务接口(interface)会变得更加复杂而在我的情况下没有真正的好处:我不需要最大的二进制传输效率,我希望良好的实现+维护效率。
最佳答案
前段时间我们在项目中遇到了相同的 WCF“限制”。简而言之,我们最终得到了
interface IStuffProvider {
List<Stuff> GetItems(int page, int pageSize); // may open large file or access database
}
是的,它和IEnumerable<Stuff> GetItems();
不一样是的,当在已收到的页面上添加/删除某些项目时,我们可能会遇到麻烦。是的,如果服务器根据 IEnumerable<Stuff>
处理项目,则需要进行一些服务器端调整。 .但它仍然是严格类型的,并没有在客户端或服务器端带来太多额外的逻辑。
关于c# - 使用 NetTcpBinding WCF 服务获取 IEnumerable<T> 语义?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26982393/