Dependency injection using Unity 2.0 and Enterprise Library 5.0

7 בנובמבר 2010

26 comments

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.

Add comment
facebook linkedin twitter email

Leave a Reply to Bohannon Cancel Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*

26 comments

  1. Tobias Manthey9 בפברואר 2011 ב 11:52

    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.

    Reply
  2. Varghesel Kerimc9 באוגוסט 2012 ב 12:15

    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.

    Reply
  3. Beall24 באוגוסט 2012 ב 3:39

    Very good article. I'm going through many of these issues as well..

    Reply
  4. Goulet22 בספטמבר 2012 ב 3:00

    I quite like looking through a post that can make
    people think. Also, thank you for allowing me to comment!

    Reply
  5. Dougherty28 באוקטובר 2012 ב 7:38

    Awesome! Its truly amazing article, I have got much clear idea concerning from
    this paragraph.

    Reply
  6. Kline31 באוקטובר 2012 ב 9:31

    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.

    Reply
  7. Vigil9 בנובמבר 2012 ב 11:13

    Excellent article. People should read this.

    Reply
  8. Hancock25 בינואר 2013 ב 22:18

    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

    Reply
  9. Roque30 בינואר 2013 ב 17:44

    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.

    Reply
  10. Heaton1 במרץ 2013 ב 10:19

    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?

    Reply
  11. Jewell20 באפריל 2013 ב 17:48

    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.

    Reply
  12. Mcmillian20 באפריל 2013 ב 18:28

    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.

    Reply
  13. Brewster20 באפריל 2013 ב 18:34

    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.

    Reply
  14. Chavis20 באפריל 2013 ב 22:36

    If you are going for best contents like me, simply go to see this website everyday because it presents quality contents,
    thanks

    Reply
  15. Cranford21 באפריל 2013 ב 8:35

    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.

    Reply
  16. Rossi21 באפריל 2013 ב 12:13

    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.

    Reply
  17. Bohannon21 באפריל 2013 ב 14:29

    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

    Reply
  18. Crook21 באפריל 2013 ב 14:34

    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.

    Reply
  19. Ison21 באפריל 2013 ב 14:52

    This website really has all the information I wanted concerning this subject and
    didn't know who to ask.

    Reply
  20. Weiner21 באפריל 2013 ב 22:30

    Hurrah! At last I got a webpage from where I can
    genuinely take helpful data concerning my study and
    knowledge.

    Reply
  21. Archuleta22 באפריל 2013 ב 4:09

    Keep on working, great job!

    Reply
  22. Bruner23 באפריל 2013 ב 13:17

    Great article! We will be linking to this particularly great article
    on our website. Keep up the good writing.

    Reply
  23. Ammons23 באפריל 2013 ב 13:28

    I every time emailed this weblog post page to all my associates, since if
    like to read it then my contacts will too.

    Reply
  24. Gerard3 במאי 2013 ב 21:10

    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!

    Reply
  25. Burgess3 במאי 2013 ב 22:41

    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

    Reply
  26. gfzuld@aol.com4 בנובמבר 2013 ב 14:00

    Dependency injection using Unity 2.0 and Enterprise Library 5.0 – Gadi Berqowitz's Blog

    Reply