Some Notes on Object Builder
Over the past few weeks I have been looking over the ObjectBuilder (Dependecy Injection) framework. I have taken a bunch of notes and will start to write some blog entries on it. This is the first....so an introduction is in order.
Introduction to Object Builder
Most software developers today understand classes and object-oriented programming. One of the basic pillars of OO is to encapsulate concepts in objects. Thus, when writing OO based software, you end up with (potentially) lots of classes. A common problem that arises with having a bunch of classes/components is how do you decouple some of the major components of your software so that you can maintain them independently. The solution is to use a loose coupling design. Dependency Injection (DI) is a design pattern that promotes loose coupling. Specifically, DI addresses the following:
In order for an implementation to support a mechanism where objects declare their dependencies and somehow their dependencies are made available, while taking into account that the dependency itself may also have dependencies, requires a container for objects. So DI is a pattern that requires a container. The container maintains the created objects. When an object says it has a dependency on another object, the DI implementation looks in it's container for the object and if it exists, it uses the object, otherwise, it creates it and puts it in the container (note that this is a simplified example).
The benefits of using a dependency injection framework are:
Object builder is a framework that can be used to implement a DI system. OB is based upon policies and strategies. Strategies are chained and get registered for a build stage. Strategies use policies. Policies are registered with OB for types. A policy is defined for types (objects in OB are defined by the type and ID). Some examples of policies in OB include:
ITypeMappingPolicy
ICreationPolicy
ISingletonPolicy
With OB you can define default policies. You can, for example, say that all objects with a given ID have to be a singleton.
// create a new builder container
Builder builder = new Builder();
// tell the builder that all of the objects in the container should be a singleton.
builder.Policies.SetDefault<ISingletonPolicy>(new SingletonPolicy(true));
Note that the ID doesn't have to be unique because an object in OB is defined by an ID and the type of the object. Thus, you can have many objects with the same ID.
There are several ways you can have a dependent service injected into an object. You can do it by requiring classes to write a constructor with the list of their dependencies. You can provided setter properties for your dependencies. And you can do for using attributes (i.e., decorate your class with your dependencies). OB supports all of these. As an example, you can define a property on a class with a dependency and then use the PropertySetterPolicy to set the dependency when the object is created. You can also define a constructor on class with it's dependencies and then use a CreationPolicy to have the dependency injected. Here are examples of how you can to this.
1) Injection using a property
// create the PropertySetterPolicy
PropertySetterPolicy propPolicy = new PropertySetterPolicy();
// define the property that needs to be set--the dependency
propPolicy.Properties.Add("IConfigurationService",new PropertySetterInfo("IConfigurationService"),typeof(IConfigurationService),"MyConfigurationService",typeof(ConfigurationServiceImpl),NotPresentBehavior.CreateNew,SearchMode.Local)));
// add the policy for the object
builder.Policies.Set<IPropertySetterPolicy>(propPolicy,typeof(IEmailService), "MyEmailServiceID");
The above code creates a new PropertySetterPolicy and tells the dependency inject to inject the IConfigurationService into the IEmailService by calling it's IConfigurationService property. When the instance of IEmailService is created by the builder, it will run through it's policies and when the PropertySetterPolicy is executed, it will set the IConfigurationService property and thus inject the dependency. Note that by saying NotPresentBehavior.CreateNew tells the builder what to do if there is not an instance of IConfigurationService when the propery needs to be injected. In this case, it is saying to create a new one. Realize that if you have multiple instances of IEmailService, they will all get the same instance of IConfigurationService.
2) Injection using a constructor
// injection via constructor is implemented by ICreationPolicy.
ICreationPolicy createPolicy = new ConstructorPolicy(new ValueParameter<FileInfo>(new FileInfo("c:\\EmailGroupsFile.txt"));
builder.Policies.Set<ICreationPolicy>(createPolicy,typeof(EmailServiceImpl),"MyEmailServiceID");
The above code tells the builder to inject the path to the list of email groups (via the FileInfo) when you create an object of type EmailServiceImpl and ID=MyEmailServiceID.
We'll see alot more on this in later posts.
Remember Me
Powered by: newtelligence dasBlog 1.8.5223.2
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
E-mail
Theme design by Jelle Druyts