8.3.2 使用Castle实现IOC和DI开发
Castle是一个著名的原生.NET开源项目,Castle的目标是实现一个全方位的整合框架,在 Castle框架下实现多个子框架的组合,这些子框架之间彼此可以独立,也可以使用其他的框架方案加以替代,Castle希望提供 one-stop shop 的框架整合方案。目前Castle最新版本说RC3,可以通过这里(http://www.castleproject.org/)来下载。它包含了:
·MicroKernel/Windsor 实现的IOC容器
·ActiveRecord实现持久层O/R M解决方案
· MonoRail实现Web框架
·Aspect#实现AOP框架
·一些辅助功能和服务
我们接着上一节的电影列表的例子来介绍一下Castle如何进行依赖注入的开发。
首先我们创建如下一个XML文件来保存电影列表:
<?xml version="1.0" encoding="utf-8" ?> <Movies> <Movie Name="A-1" Director="Zyg"/> <Movie Name="A-2" Director="Zyg"/> <Movie Name="B-1" Director="Kevin"/> <Movie Name="B-2" Director="Kevin"/> <Movie Name="B-3" Director="Kevin"/> </Movies> |
对应这个XML文件,创建一个XmlFileMovieFinder的类:
class XmlFileMovieFinder : IMovieFinder { #region IMovieFinder Members public IList<Movie> FindAll() { XmlDocument doc = new XmlDocument(); doc.Load("Movies.xml"); List<Movie> lst = new List<Movie>(); Movie m; foreach (XmlNode node in doc.GetElementsByTagName("Movie")) { m = new Movie(); m.Name = node.Attributes["Name"].Value; m.Director = node.Attributes["Director"].Value; lst.Add(m); } return lst; } #endregion } |
在项目中引用Castle.Core、Castle.DynamicProxy、Castle.MicroKernel和Castle.Windsor程序集。
然后,修改MovieLister类中的构造器来使用Castle的IOC容器,具体的步骤通过代码中的注释来说明:
class MovieLister { private IMovieFinder finder; public MovieLister() { //建立容器 WindsorContainer container = new WindsorContainer(new XmlInterpreter()); //获取IMovieFinder的实例 finder = container.Resolve<IMovieFinder>(); } |
只有上面的代码当然不能实现依赖注入,我们还需要在配置文件中添加如下内容:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <configSections> <section name="castle" type="Castle.Windsor.Configuration.AppDomain.CastleSectionHandler, Castle.Windsor" /> </configSections> <castle> <components> <component id="movieFinder.service" service="NWAD_8_1.IMovieFinder, NWAD_8_1" type="NWAD_8_1.XmlFileMovieFinder, NWAD_8_1"> </component> </components> </castle> </configuration> |
这样就可以在运行时,根据配置文件注入IMovieFinder接口的具体实现。在这个例子中,我们使用的是构造器注入方式,有兴趣的读者可以自己尝试其他注入方式。