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);
        }
    }
原文地址:https://www.cnblogs.com/xiaoweinet/p/3142263.html