根据百度百科的解释,依赖注入(Dependency Injection),简称DI,还有另外一个名字,叫做控制反转(Inversion of Control),简称IoC,是一个重要的面向对面编程的法则来削弱程序间的耦合性。
很多非凡的应用(比如HelloWorld)都是由两个或者更多的类通过彼此的合作来实现业务逻辑的,这使得每个对象都需要与其合作的对象(也就是它所依赖的对象)的引用。如果这个获取过程要靠自身实现,那么如你所见,这将导致代码高度耦合并且难以测试。
引用IoC,对象在被创建的时候,由一个调控系统内所有对象的外界实体,将其所依赖的对象的引用,传递给它。也可以说,依赖被注入到对象中。所以,控制反转是,关于一个对象如何获取他所依赖的对象的引用,这个责任的反转。
对此,我的理解是原本对象之间的耦合被转移了,所有对象都依赖到那个总的调控系统,也就是IoC容器,由IoC容器来创建和管理所有对象,但这是允许的,也是颇有益处的。
当前比较知名的IOC容器有:Pico Container、Avalon 、Spring、JBoss、HiveMind、EJB等。本人接触过的有Prism中的Unity,以及Funq。这俩分别是我在一个WPF桌面应用和一个Windows Phone 7项目中接触使用到的。
一些使用实例
Unity:
Registering Types with the Unity Container
public class OrderModule : IModule { public void Initialize() { this.container.RegisterType<IOrdersRepository, OrdersRepository>( new ContainerControlledLifetimeManager()); ... } ... }
Resolving Instances with Unity
public class OrderModule : IModule { public void Initialize() { this.container.RegisterType<IOrdersRepository, OrdersRepository>(new ContainerControlledLifetimeManager()); // Show the Orders Editor view in the shell's main region. this.regionManager.RegisterViewWithRegion("MainRegion", () =>this.container.Resolve<OrdersEditorView>()); // Show the Orders Toolbar view in the shell's toolbar region. this.regionManager.RegisterViewWithRegion("GlobalCommandsRegion", () =>this.container.Resolve<OrdersToolBar>()); } ... }
Funq:
public class ContainerService: IDisposable { void ConfigureContainer() { this.Container.Register<INavigationServiceFacade>(c => new NavigationServiceFacade(((App)Application.Current).RootFrame)); this.Container.Register<IIsolatedStorageFacade>(c => new IsolatedStorageFacade()); this.Container.Register<IDataService>(c => new DataService(c.Resolve<IIsolatedStorageFacade>())); this.Container.Register<IDialogService>(c => new DialogService()); ... } ... }
以上。