views:

292

answers:

2

I'm using the built-in system class for sending emails in .NET. It's in System.Mail namespace or something like that.

I need to add an interface to this class so I can swap it out for testing or another implementation.

To do this, I just define a class that wraps this built-in class?

Is this an example of the decorator pattern? I'm just a bit confused because the description of the decorator pattern usually states that it is used to add functionality, and I won't be adding any.

+2  A: 

No, this is not the decorator pattern, it is the proxy pattern, note: I think Microsoft expects you to make your test class inherit from the SmtpClient class, and implement the Send, AsynchSend etc yourself (in a way that they just write to a text file or whatever -- if you're wanting to plug in a test version). However if you're wanting to do it the correct way, not the microsoft way, do it the way Marc said. You will find more and more examples in .NET of interfaces not being there when they should have been.

Jesse Pepper
For info, I wasn't trying to say how to do it; I was simply explaining the decorator pattern in the context of the original question.
Marc Gravell
+2  A: 

Well, that sounds just like encapsulation (the wrapper class) and abstraction (the interface).

However, once you have the interface, you could then use the decorator pattern.

Strictly, in decorator usage each layer has the same interface; the decoration is essentially a daisy-chain of different concrete classes that (when implementing the interface) either pass the method to the next link in the chain, or do something bespoke.

(update: I'm not saying you should do it this way - this is just an example of how the decorator pattern might work, in the context of the original e-mail question)

For example, you might have an interface IEmail, a basic implementation BasicEmail (that uses the built-in .NET code), a LoggingEmail that accepts an IEmail, and just passes things along (but logs things as you go), and a ForwardingEmail that accepts an IEmail and changes the To etc (perhaps for dev/test/live purposes).

Then you could have:

`ForwardingEmail` => `LoggingEmail` => `BasicEmail` => (regular .NET classes)

(where the first three are only known as IEmail)

This allows you to extend functionality without changing the API. Very common in factory / IoC setups, and even more so with AOP.

Marc Gravell
although I don't think you answered the exact question as clearly as I did, i bumped you one because I couldn't be bothered explaining how it should be done. Wouldn't it be much nicer to say, just implememnt this interface and your TestMailSender class can plug in everywhere ISendMail is expected.
Jesse Pepper
Just saw a downvote on this - I'd love to know why...? Any feedback?
Marc Gravell
you should be so lucky - I'll balance it with +1 for the both of you for solid answers
annakata
@annakata - the funny thing is, I'm not fussed on the votes (I'm at my daily cap anyway, so that +1 only restores the 2 points I lost ;-p) - I'd just love to hear what it is that [anon] disagrees with... Oh well, I may never know.
Marc Gravell