Dependency Instantiations Should be Managed
at the Assembly Level
using an Object Factory Container
The Dependency Inversion Principle (DIP) teaches us that we should manage all dependencies at the highest level of abstraction.
The highest level is the Software Entity that has the most knowledge of the dependencies it requires.
Inversion of Control (IOC) Containers manage all Assembly dependencies at the absolute highest level of abstraction: The Assembly Level
Dependencies are Software Entities that are required by a Type that is being called on to perform some State or Behaviour activity.
They are generally Instantiated Classes that encapsulate some collection of common functionality.
The ultimate consumer of these dependencies is the Lowest Level of abstraction, the consuming type.
The State or Behaviour Entities Consume these Dependencies
.. But the actual Type Requirements are Better Known
…… At the Highest Level of Abstraction
IOC frameworks such as Microsoft Unity, StructureMap Castle Windsor and Ninject manage assembly dependencies by registering the dependencies in a “Container”.
The IOC can then instantiate a registered Type as a “Resolution” by resolving the registered Interface or Concrete to the current concrete usage.
An Interface can be Available as the Abstraction for a Number of Concrete Types
… But only One Concrete is Registered to the Interface at a Time
The consuming Software Entity can Type to the Interface rather than a selected Concrete and the IOC Container will manage the Type by resolving the instantiation to the configured Concrete when called.
The life time of the instantiation, along with garage collection when the dependency is no longer required, is managed by the IOC Container.
A IOC Container Use Case:
Let us look at the requirement for an Assembly to select how it is going to get the single Complex State DTO Response object using the Request / Response Design Pattern.
This Response Object holds all the Child Objects required to carry out the purpose of the Request Object.
We have Three Data Requirements:
A Service Layer Data Source
A Database Layer Data Source
Stub or Fake Data Source
We want to select one and only one of these at run time.
The decision is made based on either a setting in a configuration file or some event that is raised in the running Client Application.
The configuration setting is initially used and an application event can change the dependency.
In order to create an environment that we can dynamically change out dependencies we must create an Interface that creates a contract between the three data source types.
We will call this Interface: IData
… And the Three Concretes: ServicesData, RepositoryData and StubData
We will use three configuration file Boolean settings to define which concrete is to be instantiated at Application start-up.
Our Unity IOC Class will call a method that will register the IData abstraction Type to one of the three Concrete Data Types based on the settings in the configuration file flags.
We code all of the consuming types to IData not to a Concrete Data Type.
We let Unity’s lifetime container manager process and manage the concrete for us include the destruction of the Type when no longer required.
By Typing all the Data Types to IData and not to a concrete data type we can use the Inversion Of Control Principle (IOCP) to replace the concrete data type with a new one based on run time changes in the data type flags.
The abstraction of the actually usage creates an environment that is run time centric NOT compile time centric.
By complying with the Dependency Inversion Principle
and using the Inversion Of Control Principle
we are able to better manage all the dependencies
that an Assembly may require
The following two tabs change content below.
I am a Principal Architect at Liquid Hub in the Philadelphia area specializing in Agile Practices as a Certified Scrum Master (CSM). I use Test Driven Development (TDD) and Acceptance Test Driven Development (ATDD) with Behavior Driven Development (BDD) as my bridge to Agile User Stories Acceptance Criteria in a Domain Driven Design (DDD) implementing true RESTful services