简体   繁体   English

WCF OperationContract - 我应该公开哪种通用集合类型?

[英]WCF OperationContract - which generic collection type should I expose?

I have a WCF web service that has a method that returns a generic collection. 我有一个WCF Web服务,它有一个返回泛型集合的方法。 Now, my question is: Should I expose it as ICollection<T> , List<T> , IList<T> , IEnumerable<T> or something else? 现在,我的问题是:我应该将它暴露为ICollection<T>List<T>IList<T>IEnumerable<T>还是其他什么?

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> . 我认为List<T>不可能的 ,因为我想避免CA1002错误 ,但底层类型将是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 提前致谢

Keep in mind that errors such as CA1002 are really meant to apply to libraries. 请记住,CA1002等错误确实适用于库。 A WCF service is not a library, it's an endpoint that's serializing everything over SOAP, REST, etc. WCF服务不是库,它是通过SOAP,REST等序列化所有内容的端点。

You'll find that if you try to expose an interface such as ICollection<T> or IList<T> , you'll get errors that the type can't be serialized. 您会发现,如果您尝试公开诸如ICollection<T>IList<T> ,您将收到无法序列化类型的错误。 In fact, List<T> is probably the best choice here. 事实上, List<T>可能是这里的最佳选择。 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 a List<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. 当在客户端生成代理时,默认情况下它会以数组形式结束,并且很多人(如果不是大多数人)将其更改为List<T> ,因此90%的时间,无论您选择如何公开它,无论如何,客户端将会看到这种类型。

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. 我会注意到,一般来说,最好不要从WCF操作或Web服务“返回”集合。 It's more common to create a proxy class that contains the collection you want, and return that, ie: 创建包含所需集合的代理类更为常见,并将其返回,即:

[OperationContract]
OrdersResult GetOrders(OrderRequest request);

Where the proxy class might look like this: 代理类可能如下所示:

[DataContract]
public class OrdersResult
{
    [DataMember]
    public List<Order> Orders { get; set; }
}

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. 附录:WCF的真正问题是WCF不知道特定类型仅用于出站数据。 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 . 当通过WCF服务公开任何类时,WCF假定它可以是请求响应的一部分 ,并且如果它是请求的一部分,则该类型必须是具体的并且不能是不可变的 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. 你在这里别无选择,只能使用具体的可变集合类型,在大多数情况下,这意味着数组或通用列表。

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 . 在我看来,暴露序列的服务和数据合同应该清楚地表明那些序列是不可变的 ,因为它们作为DTO在线路上传播。 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. 鉴于此,我真的更喜欢使用IEnumerable<T> ,但不幸的是,这对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. 你可以得到各种奇怪的错误,特别是在延迟执行时,所以(在WCF上下文中)最好远离那些。

That really only leaves arrays , since they communicate intent best of the remaining options. 这实际上只留下了数组 ,因为它们最好地传达了其余选项的意图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM