8

I have a class with this field:

private WcfChannelFactory<IPrestoService> _channelFactory;

In the Dispose() method, I'm doing this:

if (_channelFactory != null) { _channelFactory.Dispose(); }

But that produces an error:

Cannot access explicit implementation of IDisposable.Dispose

After doing some research, it appears that I can dispose this way:

if (_channelFactory != null) { (_channelFactory as IDisposable).Dispose(); }

I don't understand two things:

  1. Why isn't Dispose() available? WcfChannelFactory<T> derives from ChannelFactory<T>, which derives from ChannelFactory, which implements IDisposable. Yet ChannelFactory doesn't have a Dispose() method. How is this possible?

  2. If I could (should?) simply call Close() on _channelFactory, why doesn't the XML documentation state that Close() will also call Dispose()? Maybe it won't? This is confusing.

Community
  • 1
  • 1
Bob Horn
  • 33,387
  • 34
  • 113
  • 219

2 Answers2

7
  1. As the Dispose method is implemented explicilty for the IDisposable interface, you can only see the method when you have a reference of the type IDisposable. The method is there, but you can't see it when you have a reference of a different type. It's similar to how a private method is only visible from code within the class itself, although it's always there.

  2. The Close method won't call Dispose for this class. The method doesn't close the factory, it starts an asynchronous closing process. When the Close method exits, the closing process is not finished, so the object can't be disposed at that time.

Guffa
  • 687,336
  • 108
  • 737
  • 1,005
  • So how am I supposed to dispose of `_channelFactory`? Am I supposed to call `Close()`? Am I supposed to call `Dispose()`? – Bob Horn May 08 '13 at 01:52
  • @Bob, nevermind. Misread your original question. Looks like you are implementing your own disposable pattern. – Anthony Pegram May 08 '13 at 01:53
  • @AnthonyPegram I can't. The method returns `_channelFactory`. The consumer is wrapping the call in a `using` so my class needs to implement `IDiposable` and dipose of it. – Bob Horn May 08 '13 at 01:55
  • @BobHorn: Use the events that are triggered in the closing process to catch when the object actually is closed. Then you can dispose it. – Guffa May 08 '13 at 02:00
  • @Guffa Thanks. And I really need to go through all that hooey just to dispose of this thing? Would it be wrong to just call Dispose like I'm doing? – Bob Horn May 08 '13 at 02:02
  • @BobHorn - No, there's nothing wrong with casting it to an IDisposable, as that's what you're supposed to do. WcfChannelFactory does not expose the Dispose() method because it does not implement the methods implicitly. The only option is to cast it. – Erik Funkenbusch May 08 '13 at 02:21
  • @BobHorn: The important thing is to close the channels and the channel factory. After that, disposing isn't that crucial as there should be no more unmanaged resources in the objects. You can dispose the channel factory once its state is `Closed`, however from the documentation is seems that the state is `Closing` once you called the `Close` method, so you would have to wait for it to actually get closed. On the other hand, I have found examples where the `Dispose` method is called right after the `Close` method, and one example from Microsoft themselves where it's not disposed at all. – Guffa May 08 '13 at 08:16
2

The Dispose method was implemented as an explicit member of the interface IDisposable. That is, the definition looks something like this:

public class WcfChannelFactory<T> : IDisposable
{
    public void IDisposable.Dispose()
    {
        ...
    }
}

Tutorial: Explicit Interface Implementation Tutorial

Timothy Shields
  • 75,459
  • 18
  • 120
  • 173