Dependency Injection 101

(It looks like Kevin Pang and I must have seen the same vision this weekend or had a close encounter flashback as he's concurrently putting together a great series on Dependency Injection for Dummies...be sure to check out his posts for another take on this subject!)

Simply put, dependency injection is the technique of supplying an object with its service dependency(s) from an external source.

If you’re unfamiliar with dependency injection or just starting down the road of object oriented programming, the above statement might have the same effect as a mathematics book when the author puts forth a new equation that is about to be analyzed.  Symptoms may include glassy eyes, nausea, and headaches.  But when taken apart, we find that the idea of dependency injection is a much simpler concept than its grandiose title implies, and is a technique that many developers use commonly, quite naturally in many cases, without even knowing it.

Encapsulation

The place to start, in understanding the motivations and implementation of dependency injection, is with the basic idea of encapsulation.  Crudely explained, encapsulation is the art of determining which bits of logic belong together and putting them into discrete objects.  This allows the details of the logic to be modified within the encapsulated object without necessarily impacting the objects which use it.  Furthermore, encapsulation provides a neat and clean way to package up reusable code to be used by many other objects without introducing code duplication.

From a real-world perspective, encapsulation is a very useful technique when building a self-aware robot to take over the world.  When building any self-aware robot, you need to start with the basics, such as mobility and sensory perception.  For example, a robot might have a stereo camera for observing the visible world, sonar sensors for detecting nearby objects around it, and touch sensors to know if it has made contact with the object it’s trying to pick up.  Just by describing it, we’re already starting to imply areas of logic that could be nicely encapsulated:  visual perception, sonar object detection, touch feedback, and mobility.

Assume for a moment that we’ll bypass the practice of encapsulation and throw all of the code for these various modules directly into the primary method which uses them, a benign method we’ll call TakeOverTheWorld, living in a .NET assembly called CommandAndControl.dll.  The code might look something like the following:

public class WorldDomination {
   public void TakeOverTheWorld() {
      // Code to open USB connection to use stereo camera
      // Code to process camera images to identify humans

      // Code to open serial port to legs for moving
      // Code to send legs serial commands to move over to location of human

      // Code to generate speech to user; e.g., "All your leaders are belong to us"
   }
}

In the code, we see the TakeOverTheWorld method taking on a lot of responsibilities and given explicit knowledge about components which are subject to change when the robot components are upgraded.  Some of the responsibilities which we’re burdening the method with include:

  • Knowing the stereo camera is connected via USB and how to open a connection to it;
  • Knowing how to process camera images to identify humans;
  • Knowing that the legs require communications to be sent via a specific serial port;
  • Knowing how to send low level communications to the legs as serial commands.

So what’s the problem you ask?  For starters, the TakeOverTheWorld method would likely be a few thousand lines long and would be immensely difficult to maintain.  Let’s suppose that we upgrade the camera to use a better stereo imaging device which now receives commands wirelessly.  You’d have to carefully, tediously walk through all of the lines of TakeOverTheWorld to find any communications with the camera, upgrade the capabilities, and test, accordingly.  But now testing is much more challenging as well.  Since all of the other code, such as the mobility code, will also run whenever we invoke TakeOverTheWorld, then we’ll need to make sure that the rest of the robot is in perfect working order while we switch out one component.  In other words, it’s simply not possible now to test the various components in isolation of each other.  This approach quickly turns into spaghetti code, becoming a maintenance nightmare, difficult to debug, and exhibiting decreasing code quality as time progresses.  What started out as a simple project to develop a robot to conquer the world is turning out to be about as effective as C-3PO…after being blasted by a storm trooper that is.

The first step that we can take, to make our robot for world domination a little easier to understand and maintain, is to encapsulate the various modules into their own, respective classes.  Let’s look at the TakeOverTheWorld code again with a sprinkling of better encapsulation by moving the camera related responsibilities to a class called StereoCamera.cs and the mobility related responsibilities to MobilePlatform.cs.  Furthermore, let’s move these two classes to a new class library assembly called Services.dll.

// Within the Services package (or class library)

public class StereoCamera {
   public void Connect() {
      // Code to open USB connection to use stereo camera
   }

   public MeaslyHuman IdentifyHumanInFieldOfVision() {
      // Code to process camera images to identify humans
   }
}

public class MobilePlatform {
   public void Connect() {
      // Code to open serial port to legs for moving
   }

   public void MoveTo(Location location) {
      // Code to send legs serial commands to move over to location 
   }
}

// Within the CommandAndControl package

public class WorldDomination {
   public void TakeOverTheWorld() {
      StereoCamera camera = new StereoCamera();
      camera.Open();
      MeaslyHuman human = camera.IdentifyHumanInFieldOfVision();

      MobilePlatform legs = new MobilePlatform();
      legs.Connect();
      legs.MoveTo(human.Location);

      // Code to generate speech to user; e.g., “All your leaders are belong to us”
   }
}

As demonstrated, we introduced two new classes, StereoCamera and MobilePlatform, and moved the related responsibilities to those classes.  We also introduced a new package as a new class library, called Services.dll, to contain the two new classes.  The package diagram now looks as the figure shown to the right.

This basic refactoring has resulted in a number of benefits:

  • There are far fewer lines of code in the TakeOverTheWorld method and easier to digest for whomever may be looking at it next;
  • The TakeOverTheWorld method is now much easier to understand the overall flow of control without getting bogged down in low level details;
  • The TakeOverTheWorld method now knows nothing about the details related to connecting to the camera via the USB connection (other than simply calling Connect), nothing about the mathematics behind processing camera images to identify humans, nor the details of opening a serial port and sending low level serial commands to move from point A to point B; and
  • The StereoCamera and MobilePlatform classes are now quite reusable from a variety of other objects that will surely need to use them.

Overall, this encapsulation refactoring has led to a design that is easier to maintain and will likely reflect in the general level of maintainability and quality.  So things are better, but we still have much to improve.  I suppose we’re beginning to resemble C-3PO, but only after Chewbacca put his head on backwards.  (OK, so C-3PO didn’t have diabolical plans for world dominion, but let’s ignore that subtlety for now.)  As we proceed, we’ll examine what other areas we’ll want to improve and learn a bit more about the definition of dependency injection along the way.

Services

Earlier, we defined dependency injection as the technique of supplying an object with its service dependency(s)…  What exactly is a service dependency?  A service, in the context of dependency injection, is any object which provides access to an external resource.  In the refactoring exercise we performed on our code, and as implied by the package diagram, two services were introduced.  The first provided access to the stereo camera; the second provided access to the legs for moving the robot around.  In your own project, services may include web services, data access objects, file manipulation utilities, third party APIs, and many others.

Because services depend on external resources (e.g., a physical component or database), they are inherently more complicated to test, require that the external resource be available when we test our code, and are subject to change when the underlying resource being managed changes (e.g., when the component is upgraded).  When considering these arguments, we want to remain loosely coupled to the services themselves.  To contrast, the refactored code above, even after applying encapsulation, is tightly coupled to the underlying services.

To illustrate the idea of tight coupling, the TakeOverTheWorld method is creating each service directly with the new keyword; i.e., the method is creating a concrete instance of the service class.  Not only does the method have a concrete dependency on the service class itself, this inherently implies that the application layer that the WorldDomination class resides in must have a direct dependency on the layer which the StereoCamera service class resides in.  This layer dependency is shown as a directional line in the above package diagram from the CommandAndControl layer to the Services layer.

In addition to having a concrete dependency on the service itself, the TakeOverTheWorld method must also know to call Open for the respective services (and presumably Close); i.e., the TakeOverTheWorld method needs to know how to create and initialize the services before it’s even able to use them.  These are further responsibilities which this method should not be concerned with.

Ideally, the TakeOverTheWorld method would be loosely coupled to the underlying services and wouldn’t have to know about such low level details of the service itself outside of calling methods such as IdentifyHumanInFieldOfVision.

Coding to Interface

The first step we can take towards making TakeOverTheWorld less tightly coupled to the service classes is to have the TakeOverTheWorld method code to the interfaces of the services rather than to the concrete classes themselves.  One might argue against introducing two new interfaces for the objects; as we add new objects, we inherently introduce additional complexity to the overall system.  Also, with interfaces, not only are we introducing a small amount of additional complexity to the overall system, but we’re also introducing indirection.  In other words, in order for someone to fully understand what’s going on at runtime, the developer will need to determine which concrete object is being used under the interface.  It shouldn’t be difficult to do so, but it does add time to understanding the overall system.  These are fair arguments and ones not to be ignored.  Whenever we are faced with a decision that will lead to a better design at the expense of added complexity, we carefully need to consider if the benefits of refactoring outweigh the penalties of added complexity.  In this case, coding to interface (and another refactoring we will do next) will lead to a more maintainable system, provide a means to readily unit test the various components in isolation, and will result in a more loosely coupled design.

Accordingly, we simply need to add two interfaces to the Services package, have the service classes implement them, and change the references in the TakeOverTheWorld method to invoke the interfaces rather than the classes themselves.  But as we’ll see, this next refactoring still leaves us tightly coupled to the service classes.  Let’s look at the code.

// Within the Services package

public interface IStereoCamera {
   void Connect();
   MeaslyHuman IdentifyHumanInFieldOfVision();
}

public interface IMobilePlatform {
   void Connect();
   void MoveTo(Location location);
}

public class StereoCamera : IStereoCamera {
   public void Connect() {
      // Code to open USB connection to use stereo camera
   }

   public MeaslyHuman IdentifyHumanInFieldOfVision() {
      // Code to process camera images to identify humans
   }
}

public class MobilePlatform : IMobilePlatform {
   public void Connect() {
      // Code to open serial port to legs for moving
   }

   public void MoveTo(Location location) {
      // Code to send legs serial commands to move over to location 
   }
}

// Within the CommandAndControl package

public class WorldDomination {
   public WorldDomination() {
      camera = new StereoCamera();
      legs = new MobilePlatform();
   }

   public void TakeOverTheWorld() {
      camera.Open();
      MeaslyHuman human = camera.IdentifyHumanInFieldOfVision();

      legs.Connect();
      legs.MoveTo(human.Location);

      // Code to generate speech to user; e.g., “All your leaders are belong to us”
   }

   private readonly IStereoCamera camera;
   private readonly IMobilePlatform legs;
}

In the code above, note that the two interfaces were introduced and now the constructor of the WorldDomination class now handles creating the service instances and setting private members, represented as interfaces, to the service instances.  The package diagram reflecting this refactoring is shown at right.

Even though the TakeOverTheWorld method is now communicating with the interfaces of the services, the class containing is still tightly coupled to the service classes due to the local instantiation of the classes within its constructor.  To further alleviate this coupling, we’re going to have to move a step “up” and introduce a package which will be responsible for creating the service dependencies and injecting them into the WorldDomination class.  Yes, we’re finally ready to see dependency injection in action.

Service Initialization and Injection

While the previous refactorings have taken us closer towards a more loosely coupled design, we still need to remove the object creation from the WorldDomination class altogether.  By introducing a new package which will contain the robot system’s “main” program, we can leverage that layer to also initialize the service dependencies and inject them into the WorldDomination class.  Let’s look at the code of the new package, called Robot, along with modifications to the WorldDomination class.  (The Services package, and the interfaces and classes therein, will remain unchanged.)  But before looking at the code, study the package diagram at right to see where the classes live and take particular note of the direction of package dependencies.  There’s one dependency that’s still problematic, which we’ll discuss after the code.

// Within the CommandAndControl package

public class WorldDomination {
   public WorldDomination(IStereoCamera camera, IMobilePlatform legs) {
      this.camera = camera;
      this.legs = legs;
   }

   public void TakeOverTheWorld() {
      // Same as before
   }

   private readonly IStereoCamera camera;
   private readonly IMobilePlatform legs;
}

// Within the new Robot package

public class Program {
   // This is the “main” method of the entire robot application.
   // I.e., it’s the method that gets called to kick off the application.
   public void Main() {
      IStereoCamera camera = new StereoCamera();
      IMobilePlatform legs = new MobilePlatform();

      WorldDomination worldDomination = new WorldDomination(camera, legs);

      worldDomination.TakeOverTheWorld();
   }
}

In the code above, the Main method initializes the services and “injects” them into the constructor of the WorldDomination class.  As you can see, the injection of service dependencies into a class is really nothing more than passing the service instances as arguments to the class instantiation.  So when it comes right down to it, the intimidating phrase “dependency injection” is really quite simple in practice.  But there’s still a problem in our implementation that could lead to design “rot” over time.  The CommandAndControl package still has a dependency on the Services package.  This is bad because during later phases of the project, without a high level of discipline, developers may forego injecting the service dependencies into the WorldDomination class, or other classes in the CommandAndControl package and simply instantiate the service classes directly using the new keyword.  This would make all the work we’ve done to this point to support dependency injection a moot point.  To enforce our design, we need to introduce a new pattern known as dependency inversion, also known as separated interface.

Separated Interface

To enforce our design, and to eliminate the package dependency from CommandAndControl to Services, we will move the service interfaces to the CommandAndControl package and reverse, or invert, the dependency direction between the two packages.   Accordingly, the refactoring steps to do this include:

  1. Copy the service interfaces from the Services package to the CommandAndControl package.
  2. Change the interface references in the WorldDomination class to refer to the interfaces now found within the CommandAndControl package.
  3. Remove the package dependency from CommandAndControl to Services.  Now add a package dependency from Services to CommandAndControl.  (In C#, this would be a matter of deleting the assembly reference from the CommandAndControl class library and adding a new assembly reference from the Services class library.)
  4. Modify the service classes, StereoCamera and MobilePlatform, to implement the interfaces now found in the CommandAndControl package.
  5. Modify the Main method, in the Main class to use the interfaces found within the CommandAndControl class.
  6. Delete the obsolete interfaces from the Services package.

With the separated interface pattern implemented, the CommandAndControl package is only aware of the service interfaces without having any dependency, whatsoever, on the service implementations.  As performed in the previous refactoring, the CommandAndControl package, the WorldDomination class specifically, is being given its service dependencies via constructor injection via initialization code found in the Robot’s main method.

With this, we have implemented a basic example, including all the required pieces, for performing dependency injection.  It introduced a number of new pieces to the overall application, but our design is now loosely coupled to the underlying services and enables us easily swap out services with new implementations, without having to recompile the CommandAndControl package, and provides the ability for test doubles, such as mocks, stubs, and fakes, to be injected into the WorldDomination class when unit testing.   (Unit testing with test doubles is beyond the scope of this article, but I encourage you to read http://xunitpatterns.com/Test%20Double.html to begin learning more about this subject.)

Dependency Injection / Inversion of Control (IoC) Containers

There’s one final topic which is appropriate to discuss when describing dependency injection:  IoC containers.  (Dependency injection is also known as “Inversion of Control,” as originally described by Robert Martin.  Interestingly enough, the development community typically uses the phrase “dependency injection” when talking about the technique itself and “IoC” when talking about dependency injection containers.  But rest assured, there is no difference whatsoever between “Dependency Injection” and “Inversion of Control (IoC).”)  An IoC Container is a utility which is leveraged to initialize and inject dependencies into the objects that use them.  While it is a bit more difficult to visualize than the “manual” dependency injection we performed in the previous refactoring step, an IoC Container is nothing more than an object factory which initializes an object and satisfies its service dependencies in the process.

With most IoC Containers (e.g., Ninject, Castle Windsor, LinFu, and many others), there are only a couple of steps required to setup and use the IoC Container:

  1. Register all of the classes which may be injected into another object.  In our carefree efforts for world domination via our robot, this would include, at minimum, registering the service classes MobilePlatform and StereoCamera.  While each IoC Container has its own means of registering a class for later retrieval, the underlying mechanism is often as simple as adding the service class’ object type to a hashtable for later lookup.   If we were using Castle Windsor with our project, the registration lines would look like the following:
    container.AddComponent("camera", 
       typeof(IStereoCamera), typeof(StereoCamera));
    container.AddComponent("mobilePlatform", 
       typeof(IMobilePlatform), typeof(MobilePlatform));
    container.AddComponent("camera", typeof(WorldDomination));
    Note that the last line registers the WorldDomination class itself. In doing so, we can let the IoC Container take care of the work of instantiating it with its service dependencies already injected. We don’t have to hand off instantiation of this class to the IoC Container, but it provides a useful benefit. Suppose the WorldDomination class needs a third service dependency provided via its constructor somewhere down the road. If we aren’t using an IoC Container to manage its creation, we’d have to look for every place where the class is created, via the new keyword, and pass in the extra dependency. If we leave its creation to the IoC Container, then we simply add the new service interface parameter to its constructor and the IoC Container will take care of the rest, assuming you’ve registered the third dependency as well.  
  2. Invoke the IoC Container to instantiate a registered object with its dependencies already injected.   For our project, the following demonstrates getting a handle to the WorldDomination class:
    WorldDomination worldDomination = (WorldDomination) 
       ServiceLocator.Current.GetService(typeof(WorldDomination));
    This line of code tells the IoC Container to return an instance of the requested class with its dependencies injected. This actually uses an IoC Container known as Common Service Locator. Since almost all IoC Containers do the same actions – registering and instantiating objects – the major IoC Container authors worked together to establish a common interface for all IoC Containers. In this way, you can register your objects with your favorite IoC Container and then register the IoC Container itself with the Common Service Locator. It’s enough to make your head spin, but leads to further decoupling to the IoC Container itself so that you can easily swap out one for another (e.g., Castle Windsor for Ninject) without modifying the code which depends on the IoC Container.

How you setup and use an IoC Container depends on the environment that you’re developing within.  For example, if you’re developing an ASP.NET MVC application, you can use an IoC Container to instantiate the controllers, injecting their dependencies via the controller’s constructor.  For example, the following two lines of code, within the Global.asax.cs file, instruct the ASP.NET MVC framework to use Castle Windsor to instantiate controllers:

IWindsorContainer container = new WindsorContainer();
ControllerBuilder.Current.SetControllerFactory(
   new WindsorControllerFactory(container));

The only thing left is to register the controller dependencies that they require for their constructors and the IoC Container takes care of the rest.

While this will be enough to gain a basic understanding of what an IoC Container is and how it is used, a bit more studying will be required to learn how to actually set up and use one.  For more information about IoC Containers, including examples of setup and usage:

Finally, for a much more thorough analysis of many of the concepts described above, I highly recommend reading Robert Martin's Agile Principles, Patterns, and Practices in C#.

Final Thoughts

Regardless of whether you’re looking to take over the world with a dominion of evil robots or simply trying to build a better web app, dependency injection and the use of an IoC Container can lead to an easy to maintain application that is loosely coupled to service dependencies.  These attributes naturally lead to better quality and happier developers.  (Both of which I would put squarely into a category known as “good.”)  But while these techniques provide many benefits, they also introduce a bit more complexity; especially when going from “manual” dependency injection, as we did in the coding example, to the use of an IoC Container.  Accordingly, your project team should carefully consider the benefits and added complexity to determine if it's right for your project.  While the use of an IoC Container would be a bit overkill for a very simple application, its use is obviously pivotal in creating self-aware robotic legions for conquering the world.

Billy McCafferty
http://wiki.sharparchitecture.net/ 

 


Posted 11-09-2009 3:26 PM by Billy McCafferty
Filed under: ,

[Advertisement]

Comments

Kevin Pang wrote re: Dependency Injection 101
on 11-09-2009 8:35 PM

Yes, we definitely must have sensed the same dependency injection void in the blogosphere over the weekend. :-)

Great post as always Billy. Keep up the great work on S#arp Architecture. :-)

Sandbox wrote re: Dependency Injection 101
on 11-10-2009 5:16 AM

Thank you...great article.

But, I have a question. What if the services are very generic, say something like a service which gets you data, then this will be used by different packages. In this case where will you put the interfaces? In a separate package?

uberVU - social comments wrote Social comments and analytics for this post
on 11-10-2009 10:51 AM

This post was mentioned on Twitter by devlicious: New Blog Post Dependency Injection 101: (It looks like Kevin Pang and I must have seen the same vi.. http://bit.ly/3r6pGF

on 11-10-2009 11:21 AM

Oslo From "Oslo" to SQL Server Modeling - It seems like Oslo has evolved their direction again. Doug Purdy announces the change from "Oslo" to SQL Server Modeling and a SQL Server Modeling CTP which will consist of: “M”

Kevin Radcliffe wrote re: Dependency Injection 101
on 11-10-2009 11:28 AM

Very nice! detailed but simple and clear.

Rob Conery also did a couple of recent posts on DI as well:

blog.wekeroad.com/.../200-page-manual-on-inversion-of-control-plus-or-minus-199

I'm really glad there is a growing resource of great developers blogging about DI. I've been using Unity and Binsor for awhile, but each time I read a post like this, it adds depth to my understanding.

Thanks for posting Billy!

Also, great job on S#arpArchitecture ^_^

Billy McCafferty wrote re: Dependency Injection 101
on 11-10-2009 11:55 AM

@Sandbox, I put my data access object interfaces (the custom ones anyway) in the "Core" layer, in a folder called RepositoryInterfaces.  For a package diagram of my projects (built on S#arp Architecture), you can take a look at github.com/.../ProjectArchitecture.PNG .  While I keep custom repository interfaces in the "Core" layer, I have an external, reusable library called SharpArch.Core which holds a generic repository interface which my project's Core layer has a direct dependency on.

@Kevin and Kevin, thanks!

Jessy Houle wrote re: Dependency Injection 101
on 11-10-2009 6:54 PM

I will be sure to direct people who ask me about DI and IOC to this excellent article.  I appreciate two things in particular about this article.

First, I appreciate your approach of teaching us about the topic.  I have read may articles and blog posts about this and other ALT.NET topics, where the author is either preaching or degrading people who do not use/understand their topic.  This automatically turns me (and many others) off.

Secondly, you have a great writing style.  You incrementally taught me about DI and IOC, which made it easier to consume.  At the same time, you kept me interested with the very geeky storyline.

Thank you very much for the article.

-Jessy Houle

Damon Wilder Carr wrote re: Dependency Injection 101
on 11-18-2009 10:05 AM

Nice one Billy. Glad to be reading your deeply insightful thoughts as always. On aspect I often add to this topic is a nice way to explain to developers why we 'favor encapsulation over specialization/inheritance'. After all in almost all cases an IoC is just an optimization, not a solution in itself. The solution it makes much less painful is the strategy pattern (making its somewhat evil cousin template less of a temptation).

This is indeed the best explanation I have for   the heart of favoring encapsulation over inheritance which is look at a system three years in based on inheritance extensibility mechanisms over one the has lived encapsulation and it is staggering. I would even say Microsoft only got good at Frameworks when this became gospel in wpf/wcf etc. in .net 3.

In my mind at least all 'great' software design must be viewed in context however and we certainly should not 'always' be optimized.

'great' might be the enemy of 'more than good enough'. When an IoC container is introduced now all of those arguments one might make such as 'well it is just not worth the extra work' start to go away. Indeed when 'better' design via injected strategies (you called them services here) becomes the same effort as less desirable sub-classing approaches IoC  starts to become central and  'just assumed to be there' when the stakes are high. And next thing you know your container helps you and your team to live happier indeed via encapsulated designs with crisply built single responsibility classes and contract driven apis.

I wanted to just say hello here mostly but also to take the opportunity to deliver a message I often find myself delivering -  When discussing IoC if the audience is not at a very high skill level with doing strategy pattern injection manually, and if the audience is not crystal on the larger issue if why encapsulation is the critical aspect of almost any non-trivial long-lived software asset, the IoC (being again just an optimization over the manual alternative) can be misunderstood...

Anyway hope you are well,

Damon Carr

Billy McCafferty wrote Message-Based Systems for Maintainable, Asynchronous Development
on 03-02-2010 2:39 AM

Preface (you know it’s good if there's a preface) In Architectural Paradigms of Robotic Control

Matthew wrote re: Dependency Injection 101
on 05-26-2010 9:21 AM

This is indeed the best explanation I have for   the heart of favoring encapsulation over inheritance which is look at a system three years in based on inheritance extensibility mechanisms over one the has lived encapsulation and it is staggering. I would even say Microsoft only got good at Frameworks when this became gospel in wpf/wcf etc. in .net 3.

In my mind at least all 'great' software design must be viewed in context however and we certainly should not 'always' be optimized.

This is really interesting topic, I'll write a paper on it or probably use the  <a href="www.bookwormlab.com/essay-writing">essay writing</a> service.

professional seo wrote re: Dependency Injection 101
on 07-22-2010 5:34 AM

In my mind at least all 'great' software design must be viewed in context however and we certainly should not 'always' be optimized. Thanks for sharing this nice blog articles.

professional seo wrote re: Dependency Injection 101
on 07-22-2010 5:35 AM

In my mind at least all 'great' software design must be viewed in context however and we certainly should not 'always' be optimized.

dissertation help wrote re: Dependency Injection 101
on 07-24-2010 12:07 AM

i m glad i found ur blog.Not everyone can provide information with proper flow. Good post. I am going to save the URL and will definitely visit again. Keep it up.

DRambox 500s wrote re: Dependency Injection 101
on 11-04-2010 9:36 PM

Thanks for your sharing!grate!

DRambox 500s wrote re: Dependency Injection 101
on 11-04-2010 9:40 PM

IT looks like a little complecated.

Cleveland Web Design Firms wrote re: Dependency Injection 101
on 11-30-2010 12:52 AM

Great work

Manish Chadha wrote re: Dependency Injection 101
on 01-05-2011 6:41 AM

Good Post. Explains the concepts of DI, Separated Interface and IOC very well.

Thank you

Accounting Assignment UK wrote re: Dependency Injection 101
on 01-14-2011 6:17 AM

Accounting Assignment UK

Very nice and helpful information has been given in this article. I must say that this is a great post. I loved reading it.

www.writers-write.co.uk/custom-accounting-help.php

Skin Care Reviews wrote re: Dependency Injection 101
on 01-17-2011 11:03 AM

I am impressed! Blog advice posted here is absolutely my friend. I neutral want to hint keep up with comments and quality work. IE browser bookmarks to your blog ethical again, I l be involved a arise finance to fathom my friends more in the tomorrow! The color of the layout is not rotten, it is easy on the eyes.

Custom Home Detailing wrote re: Dependency Injection 101
on 01-23-2011 10:03 PM

This is a very interesting. We will show this to the class. Good job.

online degree wrote re: Dependency Injection 101
on 02-02-2011 5:54 AM

Great information shared. I should have try this code once.

About The CodeBetter.Com Blog Network
CodeBetter.Com FAQ

Our Mission

Advertisers should contact Brendan

Subscribe
Google Reader or Homepage

del.icio.us CodeBetter.com Latest Items
Add to My Yahoo!
Subscribe with Bloglines
Subscribe in NewsGator Online
Subscribe with myFeedster
Add to My AOL
Furl CodeBetter.com Latest Items
Subscribe in Rojo

Member Projects
DimeCasts.Net - Derik Whittaker

Friends of Devlicio.us
Red-Gate Tools For SQL and .NET

NDepend

SlickEdit
 
SmartInspect .NET Logging
NGEDIT: ViEmu and Codekana
LiteAccounting.Com
DevExpress
Fixx
NHibernate Profiler
Unfuddle
Balsamiq Mockups
Scrumy
JetBrains - ReSharper
Umbraco
NServiceBus
RavenDb
Web Sequence Diagrams
Ducksboard<-- NEW Friend!

 



Site Copyright © 2007 CodeBetter.Com
Content Copyright Individual Bloggers

 

Community Server (Commercial Edition)