First, this is not a duplicate of IEnumerable<T> as return type for WCF methods, I think I understand that the WCF architecture only allows concrete types to be transferred that can be stuffed into a message.
Second, our setup however is not a general service but connecting up a bundle of proprietary apps via C# + WCF + NetTcpBinding + Protobuf (only) so we may have more room for some tricks that something that needs to be more binding neutral.
Third, it is neither my place nor this question's to propose a different RPC or messaging framework.
"IEnumerable semantics", for the purpose of this question, are:
- The returned sequence can be arbitrarily large -- it is therefore not possible to convert the sequence to a
List
or similar. - It is not known in advance how many items will be returned
- Caller can just use
foreach
and be done with it.
In a local assembly, a C# interface my look like this:
interface IStuffProvider {
IEnumerable<Stuff> GetItems(); // may open large file or access database
}
You can't map that directly to a WCF service. Something that might achieve the same could look like:
[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)
}
Of course, using IStuffService
will be more error prone than a IStuffProvider
and add in to the mix than many usage scenarios would involve using both service and client on the same machine, so for "user code" it wouldn't be super important to be aware that "the network" is involved, the user code is just interested in a simple interface.
One option would be of course to have a client side interface wrapper implementation, that exposes IStuffProvider
and internally forwards to and uses IStuffService
.
However, it seems it would really be desirable to not have to maintain two interfaces, one for user code, one solely for the WCF communication, especially as these applications are all tightly coupled anyway, so the additional abstraction just seems overhead.
What are the options we have here with WCF?
Note that after reading up on it, the Streamed Binding seems a poor solution, as I would still need a wrapper on the client side and the service interface would get more complex for no real gain in my case: I don't need maximum binary transfer efficiency, I would like good implementation + maintenance efficiency.
byte
s ... might be already an answer to this here ... – CookeryStream
;) (or message contracts including a stream in the body and some buffered headers) but you should be able to use protobuf on top of that for the serialization. – ManiacalStream
"Provides a generic view of a sequence of bytes" and I would like strongly typed data. – Cookery