ASP.NET MVC3 的一个重要的新特性就是允许注册一个服务点 Service Location,然后在框架中使用的能力。以前版本的 MVC 已经提供了 Service Location 和依赖注入的机会,在 MVC3 中,我们正式提供了这种能力,并且为开发者开放了多种使用的机会。
关于 Service Location 的最重要的部分就是它是可选的,这意味着如果你对 Service Location 不感兴趣,那么,你不需要被强制使用,你总是可以在不使用 Service Location 的情况下,调用自定义的函数。在以后加入新的 Service Location 的时候,也会保持向后的兼容性。
当使用注册的 Service Location 的时候,依赖于具体的使用,MVC 一般将会使用下面三种策略之一:
1. 定位一个唯一的注册服务
现在的 MVC 中使用的许多服务都注册一个实例来提供服务,例如,控制器工厂 Controller Factory,它实现了接口 IControllerFactory。对于整个应用来说,只有一个控制器工厂实例。
当 MVC 试图使用单个的注册服务的时候,它将会首先通过 Service Locator 寻找时候存在一个注册的服务实例,如果有,将使用这个服务实例,如果没有,那么将会回退到没有使用服务定位器时候注册的单个实例。
上面的处理顺序意味着使用服务定位器的用户不必担心现存项目中 MVC 的默认服务。因为当服务提供器不存在的时候,将会自动使用原来注册的服务,这种潜力也意味着可以在两个地方注册自定义的服务,但是只有通过服务器注册的服务被使用。
2. 定位多个注册的服务
在 MVC 中也有为一个服务注册多个服务实例的地方,比如说,视图引擎,视图引擎实现了接口 IViewEngine,典型情况下,MVC 提供了注册多个服务的注册点,也提供了 ViewEngines.Engines 来找到每一个视图引擎,并确定其中之一可以提供服务。还有其他的类似的场合,比如, ModelValidatorProviders.Providers 。
当 MVC 试图使用这种具有多个服务实例的服务的时候,MVC 将会通过管理多个服务实现的 Facade 来完成,Facade 将会把通过静态注册的服务实例和通过 Service Location 注册的服务实例结合在一起来选择合适的实现。在这里,服务的顺序是很重要的,通常意味着通过 Service Location 注册的服务实例要优先静态注册的实例。
类似于单实例服务注册,这意味着对于存在默认服务提供器的时候,不需要再通过 Service Location 来注册服务,这也意味着对于注册的多个服务来说,多数的容器也不必提供一个本地的排序函数,因为如果顺序是重要的,就可能需要非 Service Location 的 API。
3. 创建对象
MVC 使用服务定位器最后的策略就是直接创建对象,这最好通过依赖注入的服务来实现,我们将试图通过 Service Location 来创建对象,一个典型的例子就是控制器对象 Controller。
当 MVC 试图创建新的对象的时候,它将会请求服务定位器来创建这个对象,如果服务定位器不能完成这个任务,那么,将会回退到 MVC2 的行为,通常意味着使用 Activator.CreateInstance 来创建。
为了在 MVC3 中使用服务定位,在 MVC3 中提供了一个接口 IDependencyResolver 和一个新的类 DependencyResolver,
DependencyResolver 的定义如下:
三个静态方法提供了注册服务定位器的机制,静态属性 Current 用来获取注册的服务点。
Common Service Locator 提供了一个可以在应用程序或者框架中使用的共享的服务点,同时,项目中也提供了对于常见 IoC 的包装。
Implementation |
---|
Castle Windsor Adapter |
Spring .NET Adapter |
Unity Adapter |
StructureMap Adapter |
Autofac Adapter |
MEF Adapter now on .NET Framework 4.0 |
LinFu Adapter |
Multi-target CSL binaries |
例如,在程序中我们定义了如下的接口用于获取信息。并提供了两种实现方式:Hello 和 Hi。
项目中使用 Unity 来作为实际的 IoC 容器。类型注册通过配置文件完成。
在程序中,我们可以使用类似于下面的代码来注册服务点。
在代码中,可以直接通过服务点来获取注册的对象实例。
关于 unity 容器,可以参考
Enterprise Library - Unity Application Block 学习手册(最新版) Part 1
的 你知道Unity IoC Container是如何创建对象的吗?
注:本文内容主要参考 Brad Wilson 的 blog posts on Service Location
不知什么原因,我的电脑不能访问 Brad Wilson 的博客,手机却可以。手机看起博客来不太方便,错漏之处还请指出。