# Using delegates to avoid duplicate creation of resources

I'm writing a PCL that uses an HttpClient to go visit a few sites and extract data from them. My initial code looked like this:

public static class Download
{
{
using (var client = new HttpClient())
{
string source = await client
.GetStringAsync(videoUri);

return await client
}
}
}


I realized, however, that this would be a waste of resources if the user of my library already had a HttpClient in hand. For example:

// Caller code
using (var client = new HttpClient())
{
// Do some work with client

// Do some work with client and bytes
}


One solution could be to add an overload taking an HttpClient as a parameter, but what if the user wanted to use a WebClient instead? Or an HttpWebRequest? Or some other kind of client that wasn't availsble in the PCL?

## My solution

I decided to take delegate parameters to get the page source and to download the file based on the URI. My code now looks like this:

public static class Download
{
{
using (var client = new HttpClient())
{
() => client
.GetStringAsync(videoUri),
uri => client
.GetByteArrayAsync(uri));
}
}

{
string source = await sourceFactory();

}
}


## The problem

Hm. Wait, what if the caller is using a client that doesn't support async, like HttpWebRequest? Better add another overload taking a Func<string> and a Func<string, byte[]>. What if s/he wants to make the first call synchronous, but the second call async? Or vice versa? OK, just add 2 more overloads. Wait, what if the caller wants the whole operation to be synchronous? Let's go add 4 Download.FromYouTube overloads wrapping each of the async methods. Whoops, it turns out we need to visit another page of YouTube in case the video's signature is encrypted! Sure, let's go add 8 mor-

I think you can see where this is going. How do I maintain this flexibility without scaring the user away when Visual Studio says that there are 17 different overloads for this method?

• Aha. I just spent a while looking at this for you, hit the same wall. Interesting problems as you did, might come back and give it another try later! – Michael A Jul 3 '15 at 3:56

The problem here is that you want to be able to use a large number of unrelated objects (i.e. not implementing a common interface). One solution would be to define a usable interface and define wrapper implementations for each of these objects. Something like:

public interface IDataSource
{

Your download class would use implementations of this interface, and you could provide implementations for HttpClient, WebClient, etc. like:
public class HttpClientDataSource : IDataSource

All that said, this doesn't seem to really matter in your case. I'm not convinced that allocating an HttpClient for internal use is exactly wasteful of resources. Also, by forcing this decision onto the users of your library you've made it more complicated to use. You'll have to explain to your users how to choose between different HTTP implementations. Part of designing a good library is trading off flexibility and simplicity, and I would say the simpler interface is better.