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:
public interface ILogger
{
void Write(object message);
void Write(object message, string category);
void Write(object message, string category, int eventId);
void Write(object message, string category, int eventId, int priority);
void Write(object message, string category, int eventId, int priority, TraceEventType severity);
}
Check out the enterprise library logging implementation of the interface:
public class Logger : ILogger
{
LogWriter writer;
public Logger()
{
writer = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
}
public Logger(LogWriter logWriter)
{
writer = logWriter;
}
public void Write(LogEntry logEntry)
{
writer.Write(logEntry);
}
public void Write(object message)
{
writer.Write(message);
}
public void Write(object message, string category)
{
writer.Write(message, category);
}
public void Write(object message, string category, int eventId)
{
writer.Write(message, category, eventId);
}
public void Write(object message, string category, int eventId,int priority)
{
writer.Write(message, category,eventId, priority);
}
public void Write(object message, string category,int eventId, int priority, TraceEventType severity)
{
writer.Write(message, category, priority, eventId, severity);
}
public bool ShouldLog(LogEntry logEntry)
{
return writer.ShouldLog(logEntry);
}
}
I've also created a mock logger for testing purposes:
public class MockLogger : ILogger
{
public void Write(object message)
{
}
public void Write(object message, string category)
{
}
public void Write(object message, string category, int eventId)
{
}
public void Write(object message, string category, int eventId, int priority)
{
}
public void Write(object message, string category, int eventId, int priority, System.Diagnostics.TraceEventType severity)
{
}
}
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:
public static class LoggerManager
{
static IUnityContainer container;
/// <summary>
/// Get Current Logger
/// </summary>
/// <returns></returns>
public static ILogger GetLogger()
{
return GetLogger(string.Empty);
}
/// <summary>
/// Get Logger by unity container
/// </summary>
/// <param name="containerName">Container name</param>
/// <returns></returns>
public static ILogger GetLogger(string containerName)
{
container = new UnityContainer();
if (string.IsNullOrEmpty(containerName))
container.LoadConfiguration();
else
container.LoadConfiguration(containerName);
return container.Resolve<ILogger>();
}
}
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.
<configuration>
<configSections>
<section name="unity" type="Microsoft.Practices.Unity.Configuration.UnityConfigurationSection, Microsoft.Practices.Unity.Configuration" />
</configSections>
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="ILogger" type="MyApp.ILogger, MyApp" />
<namespace name="MyApp.Implementations" />
<assembly name="MyApp" />
<container>
<register type="ILogger" name="logger" mapTo="Logger" />
</container>
<container name="Mock">
<register type="ILogger" name="mockLogger" mapTo="MockLogger" />
</container>
</unity>
</configuration>
In my next post, I’ll be showing how to use Unity 2.0 for building decoupled layers for architecture purposes.
Thanks for putting this together.
It almost works. Only problem I got is the constructor
public Logger(LogWriter logWriter)
Unity while resolving Unity heads for the most complex constructor, hence by default Unity will chose this constructor over the default constructor. But as the class LogWriter is not mapped anywhere this will cause exception. I simply commented out this constructor and everythngs works as exepected.
For hottest news you have to pay a visit internet and on the web I found this website as a best website for most up-to-date updates.
Very good article. I'm going through many of these issues as well..
I quite like looking through a post that can make
people think. Also, thank you for allowing me to comment!
Awesome! Its truly amazing article, I have got much clear idea concerning from
this paragraph.
Hello, this weekend is fastidious in support of me,
because this point in time i am reading this great informative piece of writing here at my residence.
Excellent article. People should read this.
Hey Webmaster & People! Read this before you buy!
About Gold Box New Deals. Every Day. Lightning Deals! Deal of the day!
Check it at http://amzn.to/Olis1g
The thought of having to shove in so much fruits and vegetables at each meal deters you, so you avoid them
as far as you can. Add an hour of moderate to
intense aerobic activity and voila, you've burned 1000 calories essentially. Keep in mind you may never completely reach the ideal plan, but getting as close as you can gradually is the goal.
I was wondering if you ever considered changing
the page layout of your blog? Its very well written; I love what youve got to say.
But maybe you could a little more in the way of content
so people could connect with it better. Youve got an
awful lot of text for only having 1 or two images. Maybe you could space it out better?
Hello There. I found your blog using msn. This is a very well written article.
I'll be sure to bookmark it and return to read more of your useful info. Thanks for the post. I will certainly comeback.
You've made some good points there. I checked on the net to learn more about the issue and found most people will go along with your views on this web site.
Its such as you learn my thoughts! You appear to know a lot approximately this, such as you wrote
the e-book in it or something. I believe that you
simply can do with some percent to drive the message house a bit, but other than
that, this is wonderful blog. A fantastic read.
I will certainly be back.
If you are going for best contents like me, simply go to see this website everyday because it presents quality contents,
thanks
Does your website have a contact page? I'm having problems locating it but, I'd like to send you an
e-mail. I've got some ideas for your blog you might be interested in hearing. Either way, great website and I look forward to seeing it improve over time.
No matter if some one searches for his necessary thing, so he/she
wants to be available that in detail, so that thing is maintained over
here.
I do not know whether it's just me or if everybody else experiencing problems with your blog. It looks like some of the text in your content are running off the screen. Can someone else please comment and let me know if this is happening to them too? This might be a problem with my browser because I've
had this happen previously. Thank you
You have made some good points there. I checked on the net for more information about the
issue and found most individuals will go along with your views on this website.
This website really has all the information I wanted concerning this subject and
didn't know who to ask.
Hurrah! At last I got a webpage from where I can
genuinely take helpful data concerning my study and
knowledge.
Keep on working, great job!
Great article! We will be linking to this particularly great article
on our website. Keep up the good writing.
I every time emailed this weblog post page to all my associates, since if
like to read it then my contacts will too.
You actually make it seem so easy with your presentation
but I find this topic to be really something which I think I would never
understand. It seems too complex and extremely broad for
me. I'm looking forward for your next post, I will try to get the hang of it!
Definitely believe that that you said. Your favourite
justification seemed to be at the internet the easiest factor to take
note of. I say to you, I definitely get irked even as folks consider concerns that they just don't understand about. You controlled to hit the nail upon the highest as neatly as outlined out the whole thing without having side-effects , people could take a signal. Will probably be again to get more. Thank you
Dependency injection using Unity 2.0 and Enterprise Library 5.0 – Gadi Berqowitz's Blog