ASP.NET MVC 的依赖注入,我的整理
最近留意了一下ASP.NET MVC 的依赖注入,也看了不少相关的文章,自己也尝试了两种,分别为NInject 和Unity ,
在使用的过程中,也渐渐的了解了依赖注入的思想,于是从网上下载了一些相关的代码,直接拿来用之,包括来自微软官方的,
也有来自国外牛人博客的,但是使用当中也发生了一些问题,主要问题就是,当客户端请求一个不存在的Controller或者Action的时候
(甚至是请求一个不存在的图片或者资源),会产生异常,网上的大部分代码都会产生错误,这跟使用什么样的DI框架没有关系,
原因就出在覆盖DefaultControllerFactory 的GetControllerInstance 方法的实现上,当遇到不存的Controller 或者Action 的时候,
抛出的是自定义的异常,而不是HTTP 异常,于是打开了MVC 的源码,仔细阅读了DefaultControllerFactory.GetControllerInstance 的实现,
发现如下代码片断:
protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType) {
if (controllerType == null) {
throw new HttpException(404,
String.Format(
CultureInfo.CurrentUICulture,
MvcResources.DefaultControllerFactory_NoControllerFound,
requestContext.HttpContext.Request.Path));
}
if (!typeof(IController).IsAssignableFrom(controllerType)) {
throw new ArgumentException(
String.Format(
CultureInfo.CurrentUICulture,
MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,
controllerType),
"controllerType");
}
try {
return (IController)Activator.CreateInstance(controllerType);
}
catch (Exception ex) {
throw new InvalidOperationException(
String.Format(
CultureInfo.CurrentUICulture,
MvcResources.DefaultControllerFactory_ErrorCreatingController,
controllerType),
ex);
}
}
//注意,它抛出的是Http 404 的异常,就这么点差别,因此经过改良,我也同样的解决了这个问题,下面就是我定义的ControllerFactory:
//UnityControllerFactory.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Web.Routing;
using System.Reflection;
using Microsoft.Practices.Unity;
using System.Globalization;
/// <summary>
/// 依赖注入ControllerFactory
/// </summary>
/// <remarks>
/// 2010-09-18 [Max] 创建。
/// </remarks>
public class UnityControllerFactory : DefaultControllerFactory
{
/// <summary>
/// 创建一个Controller 类实例,覆盖基类方法
/// </summary>
/// <param name="aRequestContext">Http请求上下文对象</param>
/// <param name="aControllerType">Controller类型</param>
/// <returns>
/// 返回IController 类实例。
/// </returns>
/// <remarks>
/// 2010-10-09 [Max] 创建。
/// </remarks>
protected override IController GetControllerInstance(RequestContext aRequestContext, Type aControllerType)
{
//不适用的方式:
//if ( aControllerType == null )
//{
// throw new ArgumentNullException( "aControllerType" );
//}
//if ( !typeof( IController ).IsAssignableFrom( aControllerType ) )
//{
// throw new ArgumentException( string.Format( "{0} 不是Controller。", aControllerType.Name ), "aControllerType" );
//}
//适用的方式:
if ( aControllerType == null )
{
throw new HttpException( 404, String.Format( CultureInfo.CurrentUICulture, "未发现指定的Controller {0}。", aRequestContext.HttpContext.Request.Path ) );
}
if ( !typeof( IController ).IsAssignableFrom( aControllerType ) )
{
throw new ArgumentException( String.Format( CultureInfo.CurrentUICulture, "{0} 不是Controller。", aControllerType ), "aControllerType" );
}
try
{
IUnityContainer container = GetContainer( aRequestContext );
return (IController) container.Resolve( aControllerType );
}
catch ( Exception ex )
{
throw new InvalidOperationException( String.Format( CultureInfo.CurrentUICulture, "无法创建Controller {0}。", aControllerType ), ex );
}
}
/// <summary>
/// 获取依赖注入容器对象
/// </summary>
补充:Web开发 , ASP.Net ,