Application Block Software Factory - Sample App
Application Block Software Factory - Sample App
NOTE - see Part Two of this article here...
I've recently been working on a component for a client that requires several implementations of a base class and interface including internal class dependencies.
I'd also been lurking over a couple of blog entries on the topic of Inversion of Control Containers and the Dependency Injection pattern and trying to work out the best strategy for configuring the base provider class as well as the dependencies, and so for the first time I was thinking - hmmm.. a case for DI and a pluggable architecture.
I'm by no means an 'Alpha Geek' where DI, IoC and pluggable frameworks go, however I've been using EntLib and various providers in .Net for a while now and my curiosity was peeked when Enterprise Library 3.0 shipped with its very own Application Block Software Factory.
A brilliant blog writer by the name of Jeremy D. Miller has posted a series on DI and IoC - such as The Dependency Injection Pattern – What is it and why do I care? and Thoughts on Building Pluggable Frameworks. I'd been looking at StructureMap and Castle Windsor as possible starting points.
I've also been following the evolution of the Guidance Automation Toolkit and the Guidance Automation Extensions. There's some cool stuff going on here with the software factories released so far.
So... while StrctureMap looks like an excellent choice (although I should stress I'm really not qualified at this stage to compare the two) - I decided to try it the Microsoft way first using GAX and the Application Block Software Factory ... and here are the results - a Foo Application Block sample app (Zip).
There aren't any QuickStart sample apps for an Application Block using the software factory (at least not yet) and the docs supplied are clear but very brief and so a little digging was required. Tom Hollander has posted three video tutorials on getting started with this software factory - Enterprise Library: The Videos. The first two demonstrate the creation of providers for existing application blocks. The third one takes you through the creation of a custom application block. As an aside - the Configuration namespace in .Net 2.0 is large and daunting at first - but there's some powerful stuff in there. It helps a lot if you're familiar with the most common classes in the configuration namespace, ideally having created at least one configuration section using the ConfigurationSection base class.
I also wanted a simple App.config ready to go with my new block and configuration settings including custom settings for a provider. While Tom's video demonstrates this - the screen width was too narrow to see some of the settings he'd used including the most important reference to the section handler type.
After watching the videos and trying it out - a couple of hours later I'd got the hang of it and can now produce a custom application block, base provider and configuration classes in about five minutes; not a bad return.
The only dependencies in the new custom block are the Microsoft.Practices.EnterpriseLibrary.Common and Microsoft.Practices.ObjectBuilder namespaces - so if you're already using Entlib - these shouldn't worry you - and if you're nervous about getting into bed with GAX and GAT too soon - then with one custom application block in the bag - you can use this as a template for other projects without GAX. Creating new providers within the project is very straightforward.
One mistake I made that caused me to get hung-up for a few minutes - was a typo in the type declaration in the App.config settings file for my first concrete provider (CoolFooProvider) - if you make this mistake you'll get the following exception at runtime - "The [Assembler] attribute is not set in the configuration object type Foo.Configuration.FooProviderData." (for your base provider data class). Since this is the base type for concrete provider data class it's not decorated with the [Assembler] attribute; it's never meant to be 'assembled'. The application block couldn't find my concrete implementation (because of the config typo) and so fell back to trying to assemble the base class. Check your config file carefully if you see this message.
I also didn't like the default name of the ApplicationBlockSettings class that was created by the software factory - but this is a simple search and replace in files from VS - in this case renaming ApplicationBlockSettings to FooSettings. This is important though since this is the class that handles the section - and the one that you'll need to reference in your App.config section definition.
And very lastly - I prefer my section definition names to be camel cased (and so do the authors of the main EntLib blocks) and so a quick change to...
"public const string SectionName = "foo"" in FooSettings was in order.
My objective in the exercise was to see how quickly I could create configurable providers for the base and interface definitions for the component - including the correct settings for App.config since I did not want to depend on the designer for configuration setting creation. Like most things - it's quick and easy once you know how. Here's the link again to a working demo of a custom application block - Foo application block (Zip).
The next step in the project will be to create two new provider bases and interfaces for the nested dependencies (this is the main design goal of the block - otherwise I'd be using a simple FactoryClass to create the component). The constructor for the parent provider will simply call ProviderFactory for the nested providers based on one of the string settings in the parent provider, and of course the App.config will contain another list of possible provider entries for the child providers. If you've made it to your first custom Application Block then this next step is a breeze.
If I were more knowledgeable about StructureMap and the Castle Windows Container - I'd make some comparison comments - but I'm not (yet) so I wont. I've read enough so far to know that I'm in good shape for the first step in the process which is a good object configuration and creation strategy.
Containers are next....