Decoupling your application layers is a very important guideline when building your application.
This is important for several reasons:
· Separating your components and writing an atomic unit of codes
· Code re-use throughout the application
· Test-driven development
· Encapsulation of data sources and business logic components
Unity 2.0 enables you to achieve that using dependency injection methods.
What's "Dependency injection"?
Dependency injection (DI) is a design pattern with a core principle of separating behavior from dependency resolution. In other words: a technique for decoupling highly dependent components. You should strive to reduce dependencies between components for various reasons. This leads to a new problem, though: How can a component know all the other components it needs to fulfill its purpose?
The traditional approach was to hard-code the dependency. As soon as the database driver was necessary, the component would execute a piece of code that would load a specific driver, configure it and call the necessary methods to interact with the database. If a second database must be supported, this piece of code would have to be modified or, even worse, copied and modified.
Dependency injection offers a solution. Instead of hard-coding the dependencies, a component just lists the necessary services and a DI framework supplies these. At runtime, an independent component will load and configure the database driver and offer a standard interface to interact with the database. Again, the details have been moved from the original component to a set of new, small, database specific components, reducing the complexity of them all.
Now let's look at real scenario: you want to disconnect your dependency of logging component throughout your application.
You would do that for several reasons : to enable easy implementation of a different logger in the future and create
Testable components that are not connected to a logger and do not depend on it.
First I've created an interface for all the logging functions:
Check out the enterprise library logging implementation of the interface:
I've also created a mock logger for testing purposes:
You may notice the contractor get a default instance of the logger which is defined in the configuration via an unity container.
Unity and Unity Containers
Unity is a lightweight, extensible dependency injection container that supports interception, constructor injection, property injection, and method call injection. You can use Unity in a variety of different ways to help decouple the components of your applications, to maximize coherence in components, and to simplify design, implementation, testing, and administration of these applications.
Unity is a general-purpose container for use in any type of Microsoft® .NET Framework-based application. It provides all of the features commonly found in dependency injection mechanisms, including methods to register type mappings and object instances, resolve objects, manage object lifetimes, and inject dependent objects into the parameters of constructors and methods and as the value of properties of objects it resolves.
Dependency injection provides opportunities to simplify code, abstract dependencies between objects, and automatically generate dependent object instances. In general, you should use Unity when:
· You wish to build your application according to sound object oriented principles (following the five principles of class design, or SOLID), but doing so would result in large amounts of difficult-to-maintain code to connect objects together.
· Your objects and classes may have dependencies on other objects or classes.
· Your dependencies are complex or require abstraction.
· You want to take advantage of constructor, method, or property call injection features.
· You want to manage the lifetime of object instances.
· You want to be able to configure and change dependencies at run time.
· You want to intercept calls to methods or properties to generate a policy chain or pipeline containing handlers that implement crosscutting tasks.
· You want to be able to cache or persist the dependencies across post backs in a Web application.
Ok, so your application return ILogger but what does it mean? How do you know which logger to use?
you should create a manager that will make the decision for you.
You might want to use a default container in most cases, but you should always create an constructor for
Dynamically changing the container:
Now if you write your own unit tests projects , just call the constructor using the container name or change The default container in the configuration.
In my next post, I’ll be showing how to use Unity 2.0 for building decoupled layers for architecture purposes.