Situation: a consumer object invokes a provider object to access functionality. The consumer operates against an interface to decouple it at compile-time from the actual implementation(s) of the provider side. The provider is runtime injected via Dependency Injection. After usage, the provider instance may have to be disposed, typical to release native resources (e.g. network or database connections). However, not all provider types need to have the IDisposable interface implemented. To prevent the consumer class from being cluttered with checks on IDisposable being implemented, I delegate this to an utility class in our framework. An example of the consumer usage is now:
In the implementation of the DisposableDecorator class the check is done whether the decorated/encapsulated object implements the IDisposable interface, and if so the Dispose method is propagated on to the encapsulated object. Simple, and it keeps the consumer code clean and focussed. However, when the encapsulated object is actually a WCF proxy, something special needs to be accounted for. The standard application of the using block may then result in an undesired effect. This occurs when an exception is thrown on the channel, putting the proxy in the Faulted state. When next trying to dispose the proxy, the closing of the proxy results in throwing a new CommunicationObjectFaultedException. The latter exception hides the original exception, which has put the proxy in the Faulted state. The solution is to first check whether the encapsulated object is a WCF proxy, and if so if it's communication state is Faulted. If that's the case, then invoke the Abort method on the proxy. Otherwise just maintain the Dispose propagation.
No comments:
Post a Comment