I’ve got some code that has an awful lot of duplication. The problem comes from the fact that I’m dealing with nested IDisposable types. Today I have something that looks like:
public void UpdateFromXml(Guid innerId, XDocument someXml)
{
using (var a = SomeFactory.GetA(_uri))
using (var b = a.GetB(_id))
using (var c = b.GetC(innerId))
{
var cWrapper = new SomeWrapper(c);
cWrapper.Update(someXml);
}
}
public bool GetSomeValueById(Guid innerId)
{
using (var a = SomeFactory.GetA(_uri))
using (var b = a.GetB(_id))
using (var c = b.GetC(innerId))
{
return c.GetSomeValue();
}
}
The whole nested using block is the same for each of these methods (two are shown, but there are about ten of them). The only thing that is different is what happens when you get to the inner level of the using blocks.
One way I was thinking would be to do something along the lines of:
public void UpdateFromXml(Guid innerId, XDocument someXml)
{
ActOnC(innerId, c =>
{
var cWrapper = new SomeWrapper(c);
cWrapper.Update(someXml);
});
}
public bool GetSomeValueById(Guid innerId)
{
var result = null;
ActOnC(innerId, c => { result = c.GetSomeValue(); });
return result;
}
private void ActOnC(Guid innerId, Action<TheCType> action)
{
using (var a = SomeFactory.GetA(_uri))
using (var b = a.GetB(_id))
using (var c = b.GetC(innerId))
{
action(c);
}
}
This works, it’s just kind of clunky to parse (as a human). Does anyone have any other suggestions on how one could reduce the code duplication around nested using blocks like this? If they weren’t IDisposable then one would likely just create a method to return the results of b.GetC(innerId) … but that isn’t the case here.
I like the answer provided by BFree as a start, but I’d make a few modifications.
After doing that you can do something like:
Note that the MyCompositeDisposable will likely need to have try/finally blocks in the constructor and Dispose methods so that errors in creation/destruction properly ensure nothing ends up un-disposed.