1

I need to consume data from a WCF service, which pipes it through a stream. The data itself is contents of an archive file, so it needs additional logic, which I am splitting off into a separate class.

Now, normally, I would use a couple of nested using statements, like so:

// Inside class that does the retrieval
using (var client = new FooWcfServiceClient(endpointName))
{
    // Some logic for specifying the request
    using (var dataStream = client.SomeMethod(request))
    {
        // Consuming logic goes here
    }
}

But I do not want my retrieval class from above to be dependent on the class that does the actual work on the dataStream.

But that means, that I need to somehow pass an open stream out of the method above, without closing the connection.

The solution I came up with is to simply make a decorator like this:

class DisposingStreamDecorator : Stream, IDisposable

and then simply pass both the client and the original stream into the decorator, to be disposed later inside Dispose(). At the same time all the other members, inherited from Stream are passed onto the stream it wraps.

Is this a bad design decision? Are there any issues I am not seeing?

2

1 Answer 1

2

But I do not want my retrieval class from above to be dependent on the class that does the actual work on the dataStream.

That's what abstractions are for. If you inject that dependency, then you avoid tightly coupling your code to that dependency. And you avoid the problem you are trying to work around of Dispose being called too early.

So your code might look something like:

void Foo(Action<Stream> consume)
{
    using (var client = new FooWcfServiceClient(endpointName))
    {
        // Some logic for specifying the request
        using (var dataStream = client.SomeMethod(request))
        {
            consume(dataStream);
        }
    }
}
1
  • @Heagon, that depends on how you measure "better". To achieve this, you are having to fight the system's wish to call Dispose when the method exits. To me, that doesn't seem better than using the well established pattern of higher ordered functions (HOFs) as I'm doing here (ignoring the fact that I've used void, which means it's not strictly a HOF).
    – David Arno
    Sep 27, 2018 at 9:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.