[转载]ASP.NET MVC 3 RTM 更新(2)

baacloud免费翻墙vpn注册使用

[转载]ASP.NET MVC 3 RTM 更新(2) – Catcher In The Rye – 博客园.

三、IResolver<TService>和 SingleServiceResolver<TService>:IResolver<TService>、 MultiServiceResolver<TService>:IResolver<IEnumerable<TService>>

IResolver<TService>接口只有一个TService型的Current只读属性,返回相应类型的一个对象。这是一个有Lazy意味的轻量接口。
一个简单的IResolver<TService>接口的实现类中,Current可以返回Activator.CreateInstance创建的实例——在面向接口编程方面讲,完全是有意义的。

SingleServiceResolver 类是IResolver<TService>的实现,它用于获取单个对象,其实现原理是:在构造对象时,方法内部或作为参数指定一种默认的对 象创建(获取)”方式”——方式1,作为参数传入另一种创建(获取)”方式”——方式2和当
当两种创建(获取)对象都不成功的情况下(两种方式都成功,则会抛出异常)提供一个默认对象。

具体来说,在它公共的构造方法中,指定的方式1为DependencyResolver.Current(IDependencyResolver)。
当 调用SingleServiceResolver类的Current属性时,首先判断如果方式1不为null,则通过 DependencyResolver.Current.GetService(typeof(TService))获取一个TService对象,如果 创建(获取)成功,则尝试方式2创建(获取),如果也成功则抛出异常。
返回值的时候,先判方式1如果为null,则获取方式2的执行结果,如果结果不为null,则返回该结果,否则返回默认对象。

在 它的internal构造方法中,还允许传入默认创建(获取)方式以赋给方式1。在两个构造方法中还允许传入一个字符串标明是哪个方法在创建 SingleServiceResolver对象(或者说Current返回的对象)。在有异常发生时,可以将该字符串传入异常对象。

MultiServiceResolver 类也是IResolver<TService>的实现,它用于获取一个集合对象,其实现原理是:在构造对象时,方法内部或作为参数指定一种默 认的对象创建(获取)”方式”——方式1,作为参数传入另一种创建(获取)”方式”——方式2。
返回两种方式创建(获取)的集合的合集。

具体来说,在它公共的构造方法中,指定的方式1为DependencyResolver.Current(IDependencyResolver)。
当 调用MultiServiceResolver类的Current属性时,首先判断如果方式1不为null,则通过 DependencyResolver.Current.GetServices(typeof(TService))获取一个 IEnumerable<TService>对象,该集合对象可以没有元素但不能为null,
然后将方式2创建的集合与方式1创建(获取)的集合合并返回。

四、ControllerBuilder

我 们知道在MVC2中,Controller通过ControllerFactory创建,而ControllerFactory通过 ControllerBuilder的单例ControllerBuilder.Current的GetControllerFactory()方法获 取。类的默认构造方法中会初始化一个DefaultControllerFactory对象,并通过SetControllerFactory方法将其包 装成一个Func<IControllerFactory>实例,并赋值给_factoryThunk私有委托,当调用 GetControllerFactory方法时,返回的是该委托的执行结果。

在MVC3中,ControllerBuilder类的构造方法和GetControllerFactory方法的实现又有所不同。
ControllerBuilder 有一个IResolver<IControllerFactory>型的私有变量_serviceResolver。从上面的分析我们知 道,IResolver<IControllerFactory>有唯一的只读属性T Current,调用_serviceResolver.Current将返回一个IControllerFactory对象。
默认构造不再直接创建DefaultControllerFactory对象,只是简单的调用新增的接受一个IResolver<IControllerFactory>接口参数的构造方法。该方法目前是internal的。
internal ControllerBuilder(IResolver<IControllerFactory> serviceResolver) {
_serviceResolver = serviceResolver ?? new SingleServiceResolver<IControllerFactory>(
() => _factoryThunk(),
new DefaultControllerFactory { ControllerBuilder = this },
“ControllerBuilder.GetControllerFactory”
);
}
在 有参构造方法内部,如果传入的参数serviceResolver为null则创建一个实现了 IResolver<IControllerFactory>接口的 SingleServiceResolver<TService>类的对象赋给私有变量_serviceResolver。 ControllerBuilder.Current是一个通过默认构造函数创建的对象,用到了单例模式。所以这里serviceResolver参数是 为null的。

深入SingleServiceResolver类内部我们知道,它首先会尝试从 DependencyResolver.Current.GetService(typeof(IControllerFactory))获取 IControllerFactory对象,在默认情况会调用 Activator.CreateInstance(typeof(IControllerFactory)),当然会是null。所以最终会创建 DefaultControllerFactory作为我们的默认ControllerFactory。

假设定义了一个UnityControllerFactory:IControllerFactory。
首先,我们可以像MVC2中那样使用SetControllerFactory设置IControllerFactory
假设我们又实现了一个UnityDependencyResolver:IDenpendencyResovler,并将其设置为当前的IDenpendencyResovler。
在UnityContainer中将UnityControllerFactory映射到IControllerFactory接口,同样可以达到设置ControllerFactory的目的。

另外,GetControllerFactory方法返回的不再是像MVC2中的_factoryThunk的执行结果,而是_serviceResolver的Current属性。

赞(0) 打赏
分享到: 更多 (0)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

微信扫一扫打赏