Template Method Pattern without Inheritance

I go back and forth with Template Method. I find it convenient, but sometimes I think it can be too confusing if it is overused. I feel like the best code requires the least knowledge in order to use it. Template Method has always felt like white box re-use. Another problem I have is that it requires me to inherit in order to plug in my functionality. Well, I think I have an alternative.

I independently discovered (along with thousands of others I’m sure) a way to do Template Method without inheritance. To be honest, I don’t really know if this pattern has another name. I suspect it does. And I certainly won’t make any claims as whether or not it is good OO. I do know that I find it very convenient to be able to override behavior without having to inherit from a base class.

Here’s the relevant part of a class that I am using to call WCF services (look at the ConfigureBinding property):

public class WcfProxy<TService, TBinding> : IDisposable
    where TService : class
    where TBinding : Binding, new()
{
    public Action<TBinding> ConfigureBinding { get; set; }

    public WcfProxy()
    {
        ConfigureBinding = (binding) => { };
    }

    private ChannelFactory<TService> CreateChannelFactory(string serviceUri)
    {
        // doing some stuff here

        // create and configure binding
        var binding = new TBinding();
        ConfigureBinding(binding);

        // creating and returning ChannelFactory here

    }

    // ... more stuff is down here
}

In this example, I want to use WSHttpBinding internally but I need a way to allow the caller to configure the binding. For instance, maybe the caller needs to set send and receive timeout’s or message size limits.

In order to accomplish this, I have defined a public Action delegate property called ConfigureBinding. In the constructor of the class I initialize it to an empty method. ConfigureBinding is called right after the binding is created by my class.

In this way, the caller can provide new behavior:

var proxy = new WcfProxy<IMyService, WSHttpBinding>(uri);

proxy.ConfigureBinding = (binding) =>
                                {
                                    binding.Security.Mode = SecurityMode.Transport;
                                    binding.ReceiveTimeout = TimeSpan.FromMinutes(10);
                                    binding.SendTimeout = TimeSpan.FromMinutes(10);
                                };

// make call on the proxy here

7 Comments

  1. Peter says:

    This sounds like JavaScript-style prototype-based inheritance. I like it.

  2. Chris Martin says:

    Template Method is a pattern for inheritance.

    “Template Method lets *subclasses* redefine certain steps of an algorithm without changing the algorithm’s structure.”

    What we see here is nothing more than Dependency Injection. ;)

  3. Chris Martin says:

    As a developer, I’d much rather see:

    public class WcfProxy : IDisposable
    where TService : class
    {
    private readonly IBindingConfiguration bindingConfiguration;

    public WcfProxy(IBindingConfiguration bindingConfiguration)
    {
    this.bindingConfiguration = bindingConfiguration;
    }

    private ChannelFactory CreateChannelFactory(string serviceUri)
    {
    // doing some stuff here

    // create and configure binding
    var binding = bindingConfiguration.CreateBinding();

    // creating and returning ChannelFactory here
    return null;
    }

    // … more stuff is down here

    #region Implementation of IDisposable

    public void Dispose()
    {}

    #endregion
    }

    public interface IBindingConfiguration
    {
    Binding CreateBinding();
    }

    class ExampleBindingConfiguration : IBindingConfiguration
    {
    private readonly Action configuration;

    public ExampleBindingConfiguration(Action configuration)
    {
    this.configuration = configuration;
    }

    public ExampleBindingConfiguration() : this(b=>{})
    {}

    #region Implementation of IBindingConfiguration

    public Binding CreateBinding()
    {
    var binding = new NetTcpBinding();

    configuration(binding);

    return binding;
    }

    #endregion
    }

  4. Peter says:

    Oops, thinking back, I think the word I wanted to use is “JavaScript-style prototype-based polymorphism” which actually makes sense.

    I just did something similar for our project for building test data.

    Whether Chris’ traditional C# implementation is easier to follow for other developers is an entirely different question. I prefer the delegate/prototype-ish solution, but I’m not sure if I should deduct points for it not following the traditional Java/C# DI rule of “inject everything through an interface”.

    On our current project, the pendulum has swung way too far away from using interfaces/DI properly, and so I’m constantly trying to introduce interfaces. But I’ve also introduced several prototype-ish interface-avoiding APIs that look a lot like SystemTime.Now (see link below). We don’t have an IClockProvider interface and we’re much happier for it.

    (see http://ayende.com/blog/3408/dealing-with-time-in-tests )

    I’ve also seen some (now this is rare, but I’ve seen it) premature-interfaces in our codebase. Where someone implemented 5 interface implementations, and I come around later and determine there is only 1 hardcoded property difference between all 5. The code of course was difficult for me to understand.

    I’ve been following @bigballofmud on twitter, and he’s as harsh against Ravioli code as he is against Spaghetti code.
    http://c2.com/cgi/wiki?SpaghettiCode
    http://c2.com/cgi/wiki?RavioliCode

    The more interesting question to me ISN’T which API you or I prefer, BUT IS which API should we all prefer, and why? Is it within reason to add an interface + injected dependency where an inline delegate would do, just because more people understand the interface-based solution? How much code indirection is too much?

    Anyway, enjoy your evenings, etc. -Peter

  5. Peter says:

    I just reread my last comment. It’s terribly disjointed, and I blame twitter and bullet point-flavored work email for ruining my writing style. Maybe it’s time to blog again.

  6. Peter says:

    Maybe instead of leaving that long, rambling comment, I should have just pointed to the Caliburn.Micro source, which is probably where I’m getting my newfangled ideas from anyway. E.g. http://caliburnmicro.codeplex.com/SourceControl/changeset/view/5764a107cea0#src%2fCaliburn.Micro.Silverlight%2fViewModelBinder.cs

  7. Peter says:

    This has also been rattling around in my mind:

    http://openmymind.net/2011/5/3/Dealing-with-Now-and-why-i-am-almost-done-C%23-and-J
    with the better follow-up comment by Karl:
    http://openmymind.net/2011/5/3/Dealing-with-Now-and-why-i-am-almost-done-C%23-and-J#comment-196285793

    So maybe I’m just repeating Karl and saying: do we have to do intefaces because it’s the C# way and everyone’s comfortable with it, or can we start to make use of delegates now that they’re easy to use (since .NET 3.5)?

    Also, and I’ve never used AutoFac, but apparently it’s the IoC container that makes it much easier to inject delegates in a way that may make everyone happier.

Leave a Reply