Another way to provide a caller with optional arguments on a call is to use overloads. These can get messy when there are too many, but if you just have a few you can write them once using Extensions.

For a service, it is usual to create an interface class to define the API between the service and its consumers.

This allows you to have many implementers of the same interface which can be swapped out to do the work.. and gives you an interface to mock when you are testing the consumers in isolation.

So, say I have created a service interface, for which there will be many implementations.

One of the methods on this service is to write to a file. I want to allow the caller to optionally call the method without an encoding, in which case I will use the default encoding.

This gives me two methods

public void Write(string content) { ... }

public void Write(string content, Encoding encoding) { ... }

So I could go ahead an create an interface which requires the two methods for an implementation, but ...

I would always expect the first to call the second in the same way, passing a default for the encoding parameter.

And I am allowing the implementer to decide the default encoding, which potentially means a different implementation may have a different default. This may be desired, but generally I think it would break the Substitution Principle.

It would be better to have only one method here and supply the second method in another way.

So here is my interface

public interface IWriterService
{
    void Write(string content, Encoding encoding);
}

This asks the implementer to create one method which is given all the arguments it need to complete the job.

You could supply the second method by using a base class, this is valid, but is another constraint on the implementer as they would not be able to use there own base class.

Instead I supply the second method using an extension, passing the encoding argument from within the method, effectively making the encoding parameter optional.

public static class WriterServiceExtensions
{
    public static void Write(this IWriterService writer, string content)
    {
        writer.Write(content, Encoding.Default);
    }
}

Place this in the same namespace as the interface, that way the method is already in scope if you are calling against the interface.

Here's a test to confirm all is well ...

void extension_calls_service()
{
    const string content = "Hello";
    var moq = new Mock<IWriterService>();
    moq
        .Setup(x => x.Write(content, Encoding.Default))
        .Verifiable();

    // act
    moq.Object.Write(content);

    // assert
    moq.Verify();
}

Now I can go and code my implementations - or get someone else to - and I know that the second method will be the same and available for all.

Code

Available on GitHub as a VS2010 solution

References

http://msdn.microsoft.com/en-us/library/bb383977(v=vs.100).aspx

Tags

There are abstract classes for these kinds of overloads ;)


yea, covered that ..
"You could supply the second method by using a base class, this is valid, but is another constraint on the implementer as they would not be able to use there own base class."


Nice- never thought of adding overloads to a method using extensions!


As far as I know it is a rather new method but a very effective one. May be there another way of using overloads exist?


Post a Note

(required)

(required never shown)

On Twitter Follow MrAntix on Twitter

4 minutes ago
asaad_h89
RT @WindowsAzure: Cross-Post: Microsoft Dynamics NAV and Microsoft Dynamics GP on #WindowsAzure Infrastructure Services. http://t.co/pbkKyU…

6 minutes ago
asaad_h89
RT @WindowsAzure: Extend the functionality of your iOS app with #WindowsAzure #MobileServices. @joshtwist explains how via @ch9: http://t.c…

9 minutes ago
VisualStudio
Webinar, Neudesic presents: Live Workshop: Elevating Windows Azure Deployments - http://t.co/xetHg3X6Ow

15 minutes ago
AaronSAtDell
Microsoft Woos Developers with New Range of Windows Azure Cloud Services http://t.co/XLucg9OYZW

16 minutes ago
EricLigman
Glad they helped. :-) RT @n8ivwarrior: Huge collection of #free ebooks! Thanks @EricLigman http://t.co/57dCbiwpyn #MSPartner