“Inversion of Control, or IoC, is an abstract principle describing an aspect of some software architecture designs in which the flow of control of a system is inverted in comparison to procedural programming” wikipedia. "Inversion of Control (IoC) means that objects do not create other objects on which they rely to do their work" ~Martin Fowler.
DI is sometimes as The Hollywood Principle – "Don’t call us, we’ll call you”! Inversion of control is a concept that Dependency injection implements it and in some cases (most of the cases!) IOC implemented with DI tools that I will introduce later in this article. As mentioned in MSDN "The Dependency Injection pattern and the Service Locator pattern are specialized versions of this pattern that delineate different implementations."
factory pattern, it is all about gathering object of your domain in the factory, and to achieve that you should have a reference of the that objects in the factory, and in order to change any content of that object you should refer to the factory also, "factory pattern Define an interface for creating an object, and let subclasses decide which class to instantiate". In object-oriented design objects should have many dependencies as it is needed to do their job with no dependency and No any concrete implementation, take a look at this sample:
public class Product { public decimal Price { get{throw new NotImplementedException();} set{throw new NotImplementedException();} } }
We have a controller class that wants to Use this Product class to achieve the price of a product, Let's implement controller :
public class ProductController : Controller { Product _product = new Product(); public ActionResult list() { var price = _product.Price; return View(price); } }
now we can return the price of product in the simplest form, and there is no problem !creating an object from product makes the implementation concrete, it means that ProductController is coupled to Product and every change in product will influence to productController, we can reduce this coupling Using an interface with a little bit change in our code like this :
public interface IProduct { decimal Price { get; set; } } public class Product :IProduct { public decimal Price { get{throw new NotImplementedException();} set{throw new NotImplementedException();} } } public class ProductController : Controller { private readonly IProduct _product; public ProductController (IProduct product) { _product = product; } public ActionResult list() { var price = _product.Price; return View(price); } }
We just used an interface and constructor Injection to loose coupling, Now doesn't matter to product controller how to implement and sets the price property because it has a read-only field of IProduct interface, and every change in product class will be got in the controller. The interface is not just about declaring members of classes, as you see interface could communicate between the object (product and controller in this example). and we will not make any change in Product by changing ProductController. In DI objects shouldn't create another object, the object should get them to throw an outside source and outside source in our example is IProduct. DI is not just about using outsource, Not to influence object while using it, it is so useful when we want to Unit test our code and overall it is kinda an extreme programming.
well there is kinds of a type to implement DI in object-oriented programming, I remember these below 4 type of, but I don't remember the reference address to make you more sure about !but trust me :)
There is 4 type of injection :
- constructor injection
- setter injection
- interface injection
- service locator
let's see a simple example of each type,
Constructor injection :
public class Account { public User user; public Account(User user) { this.user = user; } }
Setter injection :
public class Account { public User User; public void SetUser(User user) { User = user; } }
interface injection :
public interface IUser { } public class Account { public IUser user; public void setUser(IUser user) { this.user = user; } }
We can also use Dependency injection in delegates and event's, see the example :
public delegate decimal calculat(int value1, int value2); public class DelegateDI { public class Product { private calculat _calculat1 { get; set; } private calculat _calculat2 { get; set; } public Product(calculat calculat1, calculat calculat2) { _calculat1 = calculat1; _calculat2 = _calculat2; } public void amethod() { _calculat1(2, 3); } } }
And in events :
private event Action _invertedMember2; public event Action InvertedMember2 { add { this._invertedMember2 += value; } remove { this._invertedMember2 -= value; } }
IOC tools
So, rather than implementing DI with some techniques there are many projects for .Net and Java platform we can use. Once Scott Hanselman listed the IOC tools in his blog :
Castle Windsor , Structure Map , Spring.NET , Autofac , Unity , Puzzle.NFactory , Ninject , S2Container.NET , PicoContainer.NET , LinFu
To be frank, I'm not familiar with all of the above, there is no need! Among the above list structure map, Ninject and castle Windsor are more famous than others, let's take a deeper look at. As is it So simple working with Ninject, I consider it first.
Ninject is an open source Dependency Injector for .NET, created by Nate Kohari, and it comes with a good set of extension and one of them is the extension for ASP.NET MVC3. add the library In your MVC project via Nuget and get started.
Suppose that you have this controller
public class HomeController : Controller { private readonly IContactRepository _contactRepository; public HomeController(IContactRepository contactRepository) { _contactRepository=contactRepository; } }
To tell the controller to use ContactRepository class when IContactRepository is called you need to make some configuration. Add a DependencyResolver class to your project with this configuration:
public class NinjectDependencyResolver : DefaultControllerFactory { private static IKernel _ninjectKernel; public NinjectDependencyResolver() { _ninjectKernel = new StandardKernel(); ConfigurDepndency(); } protected override IController GetControllerInstance(RequestContext requestContext ,Type controllerType) { return controllerType == null ? null : (IController) _ninjectKernel.Get(controllerType); } } private static void ConfigurDepndency() { _ninjectKernel.Bind<IContactRepository>().To<ContactRepository>(); }
One more line of code is needed, add this line of code in Application_Start() method of Global.asax
ControllerBuilder.Current.SetControllerFactory(new NinjectDependencyResolver());
Done! Ninject is so simple to Use and most of the MVC developer use this just because it is so fluent tool.
Structure Map
Structure map is a free open source framework for .Net and it supports Setter and Constructor Type of injection.
- Structure map provides : (as listed in its website)
- PerRequest : a new instance created for each request
- Singletone : a single instance will be shared across all requests
- ThreadLocal : A single instance will be created for each requesting thread.
- HttpContext - A single instance will be created for each HttpContext.
- Hybrid - Uses HttpContext storage if it exists, otherwise uses ThreadLocal storage
A common technique for using structure map is to have a static BootStrapper , create a class in your MVC project with below definition :
public class MvcBootStrapper { public static void ConfigurationStructureMap() { ObjectFactory.Initialize(x => { x.AddRegistry<ProductRegistery>(); }); } }
And implement the ProductRegistery :
public class ProductRegistery : Registry { public ProductRegistery() { ForRequestedType<IProductRepository>().TheDefaultIsConcreteType<ProductRepository>(); } }
And implement the ProductRepository with IProductRepository interface
public interface IProductRepository { IList<Product> Products(); } public class ProductRepository : IProductRepository { public IList<Product> Products() { throw new NotImplementedException(); } }
With above configuration you can tell the MVC controller to Use ProductRepository when the IProductRepository is called, there is the more useful feature of structure map that makes it different in comparison with other DI tools, as this article is about introducing I will cover in a separate article most of the feature of structure map!
Castle Windsor
the standard approach With Windsor is to bootstrap a single instance of the container at the entry point of the application and resolve types from that. it is a little bit hard to use Castle Windsor
Look at the example :
public interface IProductRepository { // } public class ProductRepository:IProductRepository { }
And about Windsor Configuration class, write these codes:
public class WindsorConfiguration { private IWindsorContainer _windsorContainer = new WindsorContainer(); public void ConfigureDependency() { _windsorContainer.AddComponent("Product", typeof (IProductRepository), typeof (ProductRepository)); } }
Unity
Unity is another DI container to reduce component coupling with constructor, property, and method call injectionFor using Unity we have to create a service locator, Your dependent class calls the Service Locator, passing in the type of the Service it needs and the Service Locator will return an instance of the Service.
First, we should build a UnityContainer like this :
public interface IContainerAccessor { IUnityContainer Container { get; } }
Go to Global.asax in your MVC project and type this :
public class Global : HttpApplication, IContainerAccessor { private static IUnityContainer _container; public static IUnityContainer Container { get { return _container; } set { _container = value; } } IUnityContainer IContainerAccessor.Container { get { return Container; } } }
At the End, I have to mention all of the articles that I read to learn the DI/IOC tools, you can use them:
- http://docs.structuremap.net/
- http://www.codeproject.com/Articles/162645/Dependency-Injection-IoC
- http://www.codeproject.com/Articles/33090/Using-the-Dependency-Injection-Pattern-and-Unity-C
- http://dotnet.dzone.com/articles/design-patterns-c-factory
- http://abstractcode.com/abstractblog/archive/2010/06/12/structuremap-part-0-introduction.aspx
- http://www.codeproject.com/Articles/13831/Dependency-Injection-for-Loose-Coupling
- http://www.abhisheksur.com/2011/02/inversion-of-control-practical-usage-of.html
- http://msdn.microsoft.com/en-us/library/aa973811.aspx
- http://itworksonmymachine.wordpress.com/2008/09/08/unity-dependency-injection-and-inversion-of-control-container/
- http://joelabrahamsson.com/entry/inversion-of-control-introduction-with-examples-in-dotnet
- http://www.codeproject.com/Articles/275884/Dependency-Injection-Frameworks
- http://www.codeproject.com/Articles/412383/Dependency-Injection-in-asp-net-mvc4-and-webapi-us
- http://msdn.microsoft.com/en-us/library/ff921087(v=pandp.20).aspx
- http://blogs.microsoft.co.il/blogs/gilf/archive/2008/07/01/how-to-use-unity-container-in-asp-net.aspx
- http://www.c-sharpcorner.com/uploadfile/dhanaid/introduction-to-structure-map/
Category: Software