This is something that I read a while ago in the Agile Patterns & Principles book a while ago – in fact, first time I read it was a good 18 months ago. I tried using it in a project then, and was partially successful – but am now using it “properly” on my current, and thought it was worth blabbing a little about it.
Here’s a simple example of how you might currently have a simple two-tier system talk to each other: –
You’ll notice that there’s a concrete reference between the two classes. This is often fine, but sometimes, you’ll want to abstract this relationship away (don’t you find that everything in computer science comes down to abstractions 🙂 and have an interface in between as a level of indirection. Why? Perhaps you have a number of concrete implementations and want to have some single piece of code that can act over any implementation. Or maybe (as I do in my current project) you want to mock your DAL and thus replace the “real” DAL with a stub that does stuff to help write your unit tests.
So, you create an interface on your DAL based on your DAL class, like so (note: it just so happens that Visual Studio has an “Extract Interface” refactor tool built in for exactly this sort of scenario): –
Then, on e.g. your Business Logic class, you perhaps have a constructor which by default uses the “real” DAL, and another which can take in a mock version or similar. Otherwise, your BLL class only ever talks to the interface. Great!
Except there’s a problem to this approach that’s both logical and physical – the placement of your interface. By putting it onto the DAL, the BLL still has to directly reference the DAL. It’s still physically tightly coupled to the DAL assembly; if you wanted to change it over, you’d theoretically have to redeploy both assemblies even though the BLL isn’t interested in the concrete implementation, only the interface.
How do we solve this problem? Using the DIP. This states that you effectively keep the interface – the contract – close to the client of that contract, rather than close to the server (implementation) of it. This is because when you think about it, why should a change in the physical implementation of that interface be closely coupled to the interface? Even worse, why should you be able to break the client simply by changing the server dll!?
So, you change the relationship like so:
So, now the business logic is closely related to the interface. You cannot deploy a change to the interface without redeploying the business logic layer client itself. However, there’s a catch… you may have asked yourself – how does the BusinessLogic get a reference to the real CustomerDal class? It doesn’t reference that assembly any more! So what do you do? There are a number of options. One is to have a third “controlling” assembly which references both the assemblies above and passes the concrete implementation at runtime into the business logic. This works great, but requires manual effort, and is really just writing boilerplate code to act as a factory injecting objects in.
A much more elegant solution is to use something like Unity, which is basically an object factory. You specify in your application configuration file what gets resolved to what e.g. ICustomerDal maps to CustomerDal. Then in your BLL, you simply tell Unity – “give me an object of type ICustomerDal”. This way, you never reference the physical implementation. You can mock up a fake Data Access layer in your unit tests. Your code is loosely coupled. It – just – works! 🙂
So what I’ve done compared in this final version of code is effectively take out the code which decides what object the ICustomerDal should be:
The Container class above is a simple singleton instance of the Unity Container.
UPDATE: Note that, as has been pointed out, the above code is NOT a valid implementation of the dependency injection (DI) pattern. I’ve left this intentionally as I do not want this post to confuse matters in terms of “what is DI?” versus “what is DIP?”, which are two separate concepts. You can have DIP without DI (as above), although DIP is more effective with DI, and you should probably use a container like Unity to do the grunt work for you. Similarly, you can have DI without using DIP. The two are closely related, and often go hand-in-hand, but they don’t have to.
The first time you do things this way it might feel “wrong” – you’re probably used to doing downwards-facing references. But once you get over that initial “ugh” feeling, you’ll see the elegance of doing things this way. I think that it’s really smart anyway!
I’ll talk about Unity more in detail another time, suffice it to say that you can configure the mappings between the interface and the concrete type in your app.config file, or through code, in an easy-to-read fashion.