12
返回列表 发新帖
楼主: jieforest

依赖注入Dependency Injection

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
11#
 楼主| 发表于 2009-11-12 08:50 | 只看该作者
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:
      view plaincopy to clipboardprint?
         1. container.AddComponent("camera",   
         2.    typeof(IStereoCamera), typeof(StereoCamera));  
         3. container.AddComponent("mobilePlatform",   
         4.    typeof(IMobilePlatform), typeof(MobilePlatform));  
         5. container.AddComponent("camera", typeof(WorldDomination));  

      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.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
12#
 楼主| 发表于 2009-11-12 08:51 | 只看该作者
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:
      view plaincopy to clipboardprint?
         1. WorldDomination worldDomination = (WorldDomination)   
         2.    ServiceLocator.Current.GetService(typeof(WorldDomination));  

      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:
view plaincopy to clipboardprint?

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

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:

    * Common Service Locator:  http://www.codeplex.com/CommonServiceLocator
    * Castle Windsor Tutorial:  http://www.castleproject.org/container/gettingstarted/
    * LinFu in 5 Minutes:  http://www.codeproject.com/KB/cs/LinFu_IOC.aspx
    * Using Ninject:  http://ninject.codeplex.com/wiki ... ProjectName=ninject
    * StructureMap:  http://structuremap.sourceforge.net
    * A classic IoC Overview:  http://martinfowler.com/articles/injection.html
    * Using IoC in a project:  http://wiki.sharparchitecture.net/

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#.

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
13#
 楼主| 发表于 2009-11-12 08:51 | 只看该作者
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.

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表