I had it in my mind a couple days ago that I was going to learn more about ObjectBuilder since it plays a pretty important role in a number of the frameworks and factories coming out of Microsoft Patterns and Practices.
The new version just released, 1.0.51206.0, is in the latest offerings to name a few:
- Enterprise Library, Jan 2007
- Web Client Software Factory, Jan 2007
- Web Service Software Factory, Jan 2007
Sadly I downloaded ObjectBuilder and there is absolutely no documentation and no quickstarts. This is pretty shocking since I find the documentation for the frameworks and factories above to be incredibly good. There is a powerpoint presentation with a bit of code that can be downloaded from the CodePlex site, but I was hoping for something with a bit more bite. I expected it to be more formally done since it is a big part of all these factories, etc.
ObjectBuilder is not a DI Container
One of the things you constantly here about ObjectBuilder is that it is not a DI Container, but a dependency injection framework from which you could build a container.
Okay, I can accept that, but since ObjectBuilder is a part of all these factories and a requirement in the applications these factories create, why in the heck doesn't it come with a DI Container? Doesn't it seem a little redundant to have ObjectBuilder and a separate DI Tool in the same application if one is needed? Sure... I could build a DI Container for ObjectBuilder, and John Boy could build one, and Mary Ellen could build one, etc., but it seems like it should just come with one.
ObjectBuilder Example
I did find a webcast on ObjectBuilder that helped me understand it a bit more and after a few hours I put a few lines of code together that did do a bit of dependency injection and building of objects. I think it is in the vicinity of how ObjectBuilder works. Warning: the code is rough as I was just playing...
BuilderStrategyChain chain = new BuilderStrategyChain();
// Create Strategies - Chain of Responsibility Design Pattern
chain.Add(new SingletonStrategy());
chain.Add(new TypeMappingStrategy());
chain.Add(new CreationStrategy());
// Policies
PolicyList policies = new PolicyList();
// Default Policy
policies.SetDefault<ICreationPolicy>(new DefaultCreationPolicy());
// Policy for creating SqlDataService - Singleton
policies.Set<ISingletonPolicy>(new SingletonPolicy(true), typeof(SqlDataService), null);
// Policy for creating IDataService - Use OracleDataService
TypeMappingPolicy policy = new TypeMappingPolicy(typeof(OracleDataService), "OracleDataService");
policies.Set<ITypeMappingPolicy>(policy, typeof(IDataService), null);
// Policy for MySqlDataService - Inject Required Connection String
string mySqlConnectionString = "My Connection String";
ConstructorPolicy cp = new ConstructorPolicy(new ValueParameter<string>(mySqlConnectionString));
policies.Set<ICreationPolicy>(cp, typeof(MySqlDataService), null);
// Locator - Place to put Singleton Objects
Locator locator = new Locator();
locator.Add(typeof(ILifetimeContainer), new LifetimeContainer());
// Create the context
BuilderContext context = new BuilderContext(chain, locator, policies);
// Start creating stuff... Yeah, we need a container :)
SqlDataService dataService = (SqlDataService)context.HeadOfChain.BuildUp(context, typeof(SqlDataService), null, null);
IDataService dataService2 = (IDataService)context.HeadOfChain.BuildUp(context, typeof(IDataService), null, null);
MySqlDataService dataService3 = (MySqlDataService)context.HeadOfChain.BuildUp(context, typeof(MySqlDataService), null, null);
SqlDataService dataService4 = (SqlDataService)context.HeadOfChain.BuildUp(context, typeof(SqlDataService), null, null);
IDataService dataService5 = (IDataService)context.HeadOfChain.BuildUp(context, typeof(IDataService), null, null);
MySqlDataService dataService6 = (MySqlDataService)context.HeadOfChain.BuildUp(context, typeof(MySqlDataService), null, null);
Here are the support classes for the code above:
public interface IDataService { }
public class SqlDataService : IDataService { }
public class OracleDataService : IDataService { }
public class MySqlDataService : IDataService
{
private string _connectionString;
public MySqlDataService(string connectionString)
{
_connectionString = connectionString;
}
}
You can see we are just working with a raw API here to create the list of strategies and policies for creating objects and a container would really be useful. For more information on the use of strategies and policies I recommend the webcast for an introduction.
Conclusion
I think we will see some documentation and quickstarts in ObjectBuilder 2.0 whenever it is released, but I hope they come out with a DI container. Again, it just seems silly to have ObjectBuilder and a separate DI Tool in the same application if one is using the factories and application blocks put out by Microsoft.
by David Hayden