zoukankan      html  css  js  c++  java
  • Asp.net MVC2中你必须知道的扩展点(一):Controller Factory

     Asp.net mvc2中提供很多可以扩展的地方,利用这些扩展之后,asp.net mvc使用起来更加灵活。Simone Chiaretta曾写过一篇文章:13 ASP.NET MVC extensibility points you have to know。文章中概括性的介绍了13个asp.net mvc开发人员必须知道的扩展点。我将从这13个扩展点中挑选几个常见的重要的扩展点进行详细的介绍。这篇将文章将首先介绍Controller Factory。

        Controller Factory是Asp.MVC框架中一个重要的扩展点。Controller Factory是用来创建控制器。而Controller最常用的场景之一是支持依赖注入。但是如果直接在控制器中使用依赖注入,默认情况下asp.net mvc框架将不会为你创建Controller,而且你还会得到下面这个错误,如下图:

    hhh

        产生上面错误的原因是DefaultControllerFactory使用Activator.CreateInstance来初始化控制器,而这个方法对你依赖注入的参数一无所知。

        这种情况下,我们就要使用自定义的Controller Factory。

        一个自定义的Controller Factory需要继承IControllerFactory或者继承过IControllerFactory的类,如:DefaultControllerFactory。下面代码是一个自定义的Controller factory。

    public class MyCustomControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {
            /* implement controller creation logic */
            return base.GetControllerInstance(requestContext, controllerType);
        }
    }

    在定义Controller Factory之后,需要在Application_Start()中注册一下:

    ControllerBuilder.Current.SetControllerFactory(new MyCustomControllerFactory());

    这样MVC框架将会使用你自定的Controller Factory创建Controller。

    看下面这个ProductsController,这个控制器在构造函数中接受依赖注入

    public class ProductsController : Controller
    {
        public ProductsController(IProductRepository repository,IShippingCalculator shippingCalculator, ITaxService taxService)
        {
            /* ... */
        }
        /* ... */
    }

       如果自己手动写代码创建这样的Controller是非常乏味的。幸运的是我们不需要自己手写代码去实现。因为存在很多IoC工具供我们使用。在.net中最好的依赖注入工具之一便是StructureMap,它是一个轻量级开源免费IOC框架。下面我将使用这个工具实现一个简单的MVC中依赖注入的Demo。

    1、到http://structuremapsourceforge.net/上下载这个工具。在MVC项目中引用StructureMap.dll。

    2、在Models中定义一个依赖注入的IMessageProvider接口,以及它的一个实现类StructureMapMessageProvider。

    namespace MvcApplication1.Models
    {
        public interface IMessageProvider
        {
            string GetMessage();
        }
    
        public class StructureMapMessageProvider : IMessageProvider
        {
            public string GetMessage()
            {
                return "This message was provided by StructureMap";
            }
        }
    }

    3、利用StructureMap自定义的Controller Factory代码如下:

    public class StructureMapControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
        {            
            return ObjectFactory.GetInstance(controllerType) as IController;
        }
    }

    4、定义一个静态类StructureMapBootstrapper,用来初始化StructureMap和设置StructureMapControllerFactory为项目的Controller Factory,代码如下:

    public static class StructureMapBootstrapper
    {
        public static void Initialize()
        {
            ObjectFactory.Initialize(x => x.AddRegistry(new MyStructureMapApplicationRegistry()));    
        }
    
        public static void SetControllerFactory()
        {
            var controllerFactory = new StructureMapControllerFactory();
            ControllerBuilder.Current.SetControllerFactory(controllerFactory);
        }
    }

    5、在Global.asax中使用上面的StructureMapBootstrapper类设置Controller Factory和初始化StructureMap。

    StructureMapBootstrapper.SetControllerFactory();
    StructureMapBootstrapper.Initialize();

    6、这样我们就能正常使用了。我们将HomeController设置如下:

    [HandleError]
    public class HomeController : Controller
    {
        private IMessageProvider _messageProvider;
    
        public HomeController(IMessageProvider messageProvider)
        {
            _messageProvider = messageProvider;
        }
    
        public ActionResult Index()
        {
            ViewData["Message"] = _messageProvider.GetMessage();
    
            return View();
        }
    
    }
    运行结果如下:
    hhhk 
    总结:本文简单的介绍了一下自定义Controller Factory。下一篇文章将介绍ModelBinder。
    参考:asp.net mvc 2 in action
    作者:朱祁林 出处:http://zhuqil.cnblogs.com 本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    mysql-Invalid use of group function-聚合函数不能直接使用在where后面-使用exists,外查询与子查询应条件关联
    python-数据库之pymysql模块(连接对象-游标对象-执行-获取值或者提交事务)
    python作业-99乘法表作业,注意制表符合print结束符以及外层和里层怎么确定的,以及闰年
    python学习笔记-if_while_for_break_continue
    python-python中的Debug大法
    python-常用的几种格式化方法
    python学习一周总结
    python学习笔记-列表,字典,以及函数返回值
    python-注释,变量命名和规范笔记
    OpenJudge 求重要逆序对数
  • 原文地址:https://www.cnblogs.com/flish/p/4682227.html
Copyright © 2011-2022 走看看