WCF OperationContract - 我应该公开哪种通用集合类型?
我有一个 WCF Web 服务,它有一个返回通用集合的方法。现在,我的问题是:我应该将其公开为 ICollection
、List
、IList
、IEnumerable
还是其他什么?
我认为 List
是不可能的,因为我想避免 CA1002 错误,但基础类型将是 List
。
我真的很想听听你对此的看法,最好能很好地解释你为什么这么想。
提前致谢
I have a WCF web service that has a method that returns a generic collection. Now, my question is: Should I expose it as ICollection<T>
, List<T>
, IList<T>
, IEnumerable<T>
or something else?
I suppose that List<T>
is out of the question since I want to avoid CA1002 errors, but the underlying type will be a List<T>
.
I am really interested in hearing your takes on this, preferably with a good explanation of why you think what you think.
Thanks in advance
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
请记住,诸如 CA1002 之类的错误实际上适用于库。 WCF 服务不是一个库,它是一个通过 SOAP、REST 等序列化所有内容的端点。
如果您尝试公开诸如
ICollection
或之类的接口,您会发现这一点IList
,您会收到类型无法序列化的错误。事实上,List
可能是这里的最佳选择。当客户端生成代理时,默认情况下它最终会以数组形式结束,并且许多(如果不是大多数)人将其更改为List
,所以 90% 的情况下,无论如何您选择如何公开它,这就是客户无论如何都会看到的类型。我要指出的是,一般来说,最好不要从 WCF 操作或 Web 服务中“返回”集合。更常见的是创建一个包含所需集合的代理类,然后返回该集合,即:
代理类可能如下所示:
这样,如果您决定需要向请求或响应添加更多数据,您可以可以这样做而不会对客户端造成重大更改。
附录:WCF 的真正问题是 WCF 不知道特定类型仅用于出站数据。当通过 WCF 服务公开任何类时,WCF 假定它可以是该类型的一部分。 请求或响应,如果它是请求的一部分,则类型必须是具体的 > 和不能是不可变的。这就是所有其他愚蠢限制(例如要求属性设置者)的原因。
这里你别无选择,只能使用具体的、可变的集合类型,在大多数情况下,这意味着数组或通用列表。
Keep in mind that errors such as CA1002 are really meant to apply to libraries. A WCF service is not a library, it's an endpoint that's serializing everything over SOAP, REST, etc.
You'll find that if you try to expose an interface such as
ICollection<T>
orIList<T>
, you'll get errors that the type can't be serialized. In fact,List<T>
is probably the best choice here. When a proxy gets generated on the client side, it ends up as an array by default, and many if not most people change it to aList<T>
, so 90% of the time, no matter how you choose to expose it, that's the type that the client is going to see anyway.I'll note that it's generally good practice not to "return" a collection at all from a WCF operation or a web service in general. It's more common to create a proxy class that contains the collection you want, and return that, i.e.:
Where the proxy class might look like this:
That way if you decide you need to add more data to either the request or the response, you can do so without causing breaking changes to the client.
Addendum: The real issue here with WCF is that WCF doesn't know that a particular type is used only for outbound data. When any class is exposed through a WCF service, WCF assumes that it can be part of either a request or a response, and if it is part of a request, then the type must be concrete and cannot be immutable. That's the reason for all the other silly restrictions like requiring property setters.
You simply have no choice here but to use a concrete, mutable collection type, and in most cases that means either an array or a generic list.
在我看来,公开序列的服务和数据契约应该清楚地表明这些序列是不可变的,因为它们作为DTO通过网络传输。添加和删除从不同层收到的序列没有多大意义。相反,您想要读取该数据并用它做一些事情。
鉴于此,我确实更喜欢使用
IEnumerable
,但不幸的是,这在 WCF 中效果不佳。您可能会遇到各种奇怪的错误,特别是在延迟执行时,因此(在 WCF 上下文中)最好远离这些错误。实际上只剩下数组,因为它们在其余选项中传达了最好的意图。
In my opinion, service and data contracts that expose sequences should clearly signal that those sequences are immutable, since they are travelling over the wire as DTOs. It doesn't make a lot of sense adding and removing on a sequence that you received from a different tier. Rather, you want to read that data and do something with it.
Given that, I would really prefer to use
IEnumerable<T>
, but unfortunately, this just doesn't work well with WCF. You can get all sorts of weird errors, particularly when it comes to deferred execution, so (in a WCF context) it's best to stay away from those.That really only leaves arrays, since they communicate intent best of the remaining options.