zoukankan      html  css  js  c++  java
  • IOC运用到MVC中

    IOC可以摒弃掉类中类的紧耦合,让设计和重用更简单,将IOC加入到MVC中的实现非常简单,那么有哪几种方法?它们的实现又是什么原理呢?

    IOC在MVC中的注入,主要是在获取Controller对象中实现,也就是在获取Controller对象的方法中增加注入的相关实现就可以了,这些入口均是在DefaultControllerFactory类中,目前获取Controller的有如下方法:

    (1)重写DefaultControllerFactory中的GetControllerInstance方法

    源码:

     1   protected internal virtual IController GetControllerInstance(RequestContext requestContext, Type controllerType)
     2         {
     3             if (controllerType == null)
     4             {
     5                 throw new HttpException(404,
     6                                         String.Format(
     7                                             CultureInfo.CurrentCulture,
     8                                             MvcResources.DefaultControllerFactory_NoControllerFound,
     9                                             requestContext.HttpContext.Request.Path));
    10             }
    11             if (!typeof(IController).IsAssignableFrom(controllerType))
    12             {
    13                 throw new ArgumentException(
    14                     String.Format(
    15                         CultureInfo.CurrentCulture,
    16                         MvcResources.DefaultControllerFactory_TypeDoesNotSubclassControllerBase,
    17                         controllerType),
    18                     "controllerType");
    19             }
    20             return ControllerActivator.Create(requestContext, controllerType);
    21         }

    重写后:

    public class DefaultFactoryIOC:DefaultControllerFactory
        {
            private IKernel kernel;
            public DefaultFactoryIOC()
            {
                kernel = new StandardKernel();
                kernel.Bind<IRespo>().To<Respo>();
            }
            protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
            {
                return (IController)kernel.TryGet(controllerType);
            }
        }
    Global中定义
        ControllerBuilder.Current.SetControllerFactory(new IOCTest.DefaultFactoryIOC());

    (2)对前面的方法再一次观察发现,实例化Controller最后是交给了ControllerActivator.Create(requestContext, controllerType)方法,也就是如果能够实现或者重写这个方法就能实现注入,那么ControllerActivator来自于

      public DefaultControllerFactory(IControllerActivator controllerActivator)
                : this(controllerActivator, null, null)
            {
            }

    接下来实现IControllerActivator这个接口,完成第二种IOC方法

    public class ControllerActivatorIOC:IControllerActivator
        {
            private IKernel kernel;
            public ControllerActivatorIOC()
            {
                kernel = new StandardKernel();
                kernel.Bind<IRespo>().To<Respo>();
            }
            public IController Create(System.Web.Routing.RequestContext requestContext, Type controllerType)
            {
                return (IController)kernel.TryGet(controllerType);
            }
        }
    Global中
      protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                /*DefaultFactoryController*/
                //ControllerBuilder.Current.SetControllerFactory(new IOCTest.DefaultFactoryIOC());
    
                IControllerActivator controlleract = new IOCTest.ControllerActivatorIOC();
                DefaultControllerFactory defaultControllerFactory = new DefaultControllerFactory(controlleract);
                ControllerBuilder.Current.SetControllerFactory(defaultControllerFactory);
    
            }

    (3)接着最后一个方法仍然是从IControllerActivator 中,再DefaultContollerFactory这个Controller激活类中,默认调用实现IControllerActivator的类是DefaultControllerActivator,

    它实现了以上这个Create方法

      
    private Func<IDependencyResolver> _resolverThunk;
    public IController Create(RequestContext requestContext, Type controllerType) { try { return (IController)(_resolverThunk().GetService(controllerType) ?? Activator.CreateInstance(controllerType)); } catch (Exception ex) { throw new InvalidOperationException( String.Format( CultureInfo.CurrentCulture, MvcResources.DefaultControllerFactory_ErrorCreatingController, controllerType), ex); } }

    从上可知,Create方法最后会采用那个默认的构造或者第三方实现_resolverThunk的类来实现,而这个_resolverThunk就是从IDependencyResolver接口而来,所以实现IDependencyResolver就可以达到DI的目的

        public class DependencyResolverIOC:IDependencyResolver
        {
            private IKernel kernel;
            public DependencyResolverIOC()
            {
                kernel = new StandardKernel();
                kernel.Bind<IRespo>().To<Respo>();
            }
            public object GetService(Type serviceType)
            {
                var obj = this.kernel.TryGet(serviceType);
                return obj;
            }
    
            public IEnumerable<object> GetServices(Type serviceType)
            {
                return this.kernel.GetAll(serviceType);
            }
        }
    // Note: For instructions on enabling IIS6 or IIS7 classic mode, 
        // visit http://go.microsoft.com/?LinkId=9394801
        public class MvcApplication : System.Web.HttpApplication
        {
            protected void Application_Start()
            {
                AreaRegistration.RegisterAllAreas();
    
                /*DefaultFactoryController*/
                //ControllerBuilder.Current.SetControllerFactory(new IOCTest.DefaultFactoryIOC());
    
                //IControllerActivator controlleract = new IOCTest.ControllerActivatorIOC();
                //DefaultControllerFactory defaultControllerFactory = new DefaultControllerFactory(controlleract);
                //ControllerBuilder.Current.SetControllerFactory(defaultControllerFactory);
    
                DependencyResolver.SetResolver(new IOCTest.DependencyResolverIOC());
    
                WebApiConfig.Register(GlobalConfiguration.Configuration);
                FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
                RouteConfig.RegisterRoutes(RouteTable.Routes);
            }
        }
  • 相关阅读:
    虚基类、虚函数与纯虚函数
    从尾到头打印链表
    Login
    (转)学习技术的三部曲:WHAT、HOW、WHY
    win7mstsc连接电脑
    C#面试题
    ASP.net C#笔记 (一)新建三层项目
    asp.net (一) 语法
    云服务器寻找
    VB.net笔记 (二)内置对象
  • 原文地址:https://www.cnblogs.com/xiaoweinet/p/3142263.html
Copyright © 2011-2022 走看看