Miguel Castro spoke Wednesday night at the Cincinnati .NET User Group on Sexy Extensibility Patterns. Not just extensibility patterns, sexy extensibility patterns. Miguel was in town courtesy of INETA, and was on his first visit to Ohio.
He started the presentation talking about the reasons to consider extensibility. As a consultant, he leverages extensibility to allow his clients to change and add to applications without needing to touch the main code; using a well designed extensibility mechanism, you can just drop an assembly in a folder and the new function will be included as part of the application. To design for extensibility, you need to think about where things may change and create abstractions (interfaces). So instead of writing code to open a file, read lines from the file, and write those lines to a log file, you should think about an interface to determine the data source, get the data, and write data to the destination. It's a subtle, but important shift.
Most of his presentation was centered around a greatly simplified version of a scenario he had with an actual client. The first version of code he showed was hard coded to open a file, read the lines, then write the lines to a log file. He then proposed the scenario that the client wanted to read the data from a database rather than a file, so he introduced an interface that he first implemented using code that was copied and pasted from his hard-coded version. So it did the same thing, it was just in a separate assembly, and the host program was written so that you could just change an entry in the app.config file and replace the execution logic. After that, he implemented a version that read from a database rather than a text file. And he was able to change the function of the host program by just changing the app.config. He termed this first version of extensibility the provider model and compared it to the many built-in providers for .NET, such as the ASP.NET membership provider and the ADO.NET provider model.
He called the next extensibility mechanism plug-ins. Plug-ins allow you to add multiple functions to be performed as opposed to the providers, which allow only one. For the plug-ins example, he proposed a scenario where after the data was read, but before it was logged, the client wanted to email the data to people and archive the data. Both operations do something with the data and can be grouped under one interface. So he implemented two version of the interface and added both to a section in the app.config. Using this scheme, he could add another action to execute with the data without changing the main processing code.
The last extensibility mechanism he described was modules, named for its similarity to the ASP.NET HttpModule. Modules provide multiple points of logically related extension points in one class by leveraging events. Just like IHttpModule, he created an interface with an Init method that receives a class with several events. The module simply attaches handlers to the events of interest. Then the host code fires the events and lets every module do whatever processing is necessary. Using the HttpModule as a model seems like a good idea and I'm going to keep my eye out for opportunities to use it.
If these techniques sound interesting, I would strongly recommend that you look at the code. He spent much of the presentation talking about the code, and without repeating it here, I can't do it justice. You can download the slides and sample code (C# and VB.NET) for the presentation on the Steel Blue Solutions site (you will need to register, and wait for the email to confirm before you try to log in.)
The idea of extensibility has definitely been on the mind of the .NET framework developers as evidenced by the addition of the Add-Ins and Extensibility features in the .NET 3.5 framework. I've been working with some of these features in WPF, and once you get past the amount of plumbing code that needs to be written, it seems to work well. It's great to see a mechanism in the framework itself to accommodate extensibility.
Back in 2003, I actually did several presentations using similar techniques for both Delphi and .NET 1.0. You can download a Word doc and code for the .NET portion here. You can check out the presentations page on my site to see the other related presentations if you're interested in the Delphi code.