先建立接口再实现类的开发方式又称为"控制反转"模式,英文名称为"Inversion of Control",简称IoC。也许有人不快习惯这样的开发方法,但在规划较大的软件架构时,这种方法却可以有效降低类之间互相依赖的情况,不但能增加架构的弹性,也能有效降低软件的复杂度。

    如果不考虑控制反转的情况,采用比较直接的开发方式,当然是不用先建立接口而直接建立类,然后直接在应用层中调用即可。如此一来,应用层的对象就会与BLL层对象高度相依。这样的相依性会导致这两个类无法拆开。为什么要拆开这两个类呢?由于单元测试是软件测试的最小单位,所以如果日后导入单元测试,那么这种两个类彼此相依的状况就会导致单元测试难以进行。

    为了避免应用层对象与BLL层对象或BLL层对象与DAL层对象产生相依性,我们需要替BLL层对象加上一个IBLL接口,而在应用层对象中则可以通过IBLL接口来执行BLL对象的动作。但即使是这样,BLL对象与应用层对象的相依性还是存在,因为在应用层对象构造符处还是需要建立实体的BLL对象,如 IBLL _bll = new BLL();

    为了解决耦合度问题,引入了控制反转IoC。目前网络上可以使用的控制反转容器有很多,例如微软的Unity、Castle Windsor、Autofac、StructureMap等都拥有广大的支持者。下面就简单介绍我在项目中运用的Autofac,也是目前性能比较好的控制反转容器之一。

下载地址:http://code.google.com/p/autofac/

    笔者参考了一些关于MVC2的教程,使用的是VS2008环境,与我项目运用VS2010和MVC3环境有一定出入,导致在运用Autofac时走了一些弯路。关于MVC2项目中如何通过Autofac实现控制反转这篇文章就不再累述。下面直接讲关于MVC3中运用方法。

    在项目中引入Autofac.dll、Atuofac.Integration.Web.dll和Autofac.Integration.Mvc.dll在Global.asax文件中MvcApplication类的Application_Start()方法中加入以下代码:

var builder = new ContainerBuilder();

builder.RegisterType<BLL>().As<IBLL>();

builder.RegisterTypes(Assembly.GetExecutingAssembly())

.Where(t = t.Name.EndWith("Repository"))

.AsImplementedInterfaces();
builder.RegisterControllers(typeof(MvcApplication).Assembly);
var container = builder.Build(); DependencyResolver.SetResolver(new AutofacDependencyResolver(container));

以上红色下划线部分是控制部分,根据项目内容进行写入,采用了两种方式,第一种方法一次只对就一个类,第二种方法是一次对应一类类,意思就是以"Repository"结束的类和接口都匹配上。

Controller里写一个构造函数:

 

Private IBLL bll;

Public AccountController(IBLL _bll)

{

    Bll = _bll;

}

这样几行代码就实现了Controller的控制反转。如此一来,整个MVC3项目的所有Controller中将完全不会出现建立接口实例的程序,所有建立BLL类实例的控制权已经完全交给Autofac了。