主要概念:

注:以下概念是自我理解,不是很准确。

  • IOC:Inversion of Control(控制反转)。

本来对象创建是通过使用类内部进行创建,现在把对象创建交给container(容器)管理

打个比方好比现在华数网络(container),你去华数网络营业厅注册服务(普通电视,高清电视,华数网络),等你回家你接上电视,华数网络(container)就可以将普通电视或高清电视的对象返回给你;当你接上电脑时,华数网络(container)就将华数网络对象返回给你。

  • Unity

Unity是微软的一款轻量级的容器。

namespace MVCIOC.IOC
{
    public class HttpContainerBuilder
    {
        public static readonly IUnityContainer UnityContainer = new UnityContainer();

        public static void Register()
        {
            //注册Service1和Service2
            UnityContainer.RegisterType(typeof (Service1));
            UnityContainer.RegisterType(typeof (Service2));
            //注册Control
            UnityContainer.RegisterType(typeof (HomeController));
        }
    }
}

这个往UnityContainer中注册了两个Servie1和Service2两种类型,并注册了HomeController

namespace MVCIOC.IOC
{
    public class UnityDependencyResolver : IDependencyResolver
    {
        IUnityContainer container;
        public UnityDependencyResolver(IUnityContainer UnityContainer)
        {
            this.container = UnityContainer;
        }

        public object GetService(Type serviceType)
        {
            return container.Resolve(serviceType);
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return container.ResolveAll(serviceType);
        }
    }
}

 IDependencyResolver是依赖解析器接口

protected void Application_Start()
        {
            HttpContainerBuilder.Register();
            DependencyResolver.SetResolver(new UnityDependencyResolver(HttpContainerBuilder.UnityContainer));

            AreaRegistration.RegisterAllAreas();

            RegisterGlobalFilters(GlobalFilters.Filters);
            RegisterRoutes(RouteTable.Routes);
        }

注册类型,并设置依赖解析器(实现IDependencyResover接口的对象),这样UnityDependencyResolver接管了部分依赖注入类

这样理论上里说,Sevice1,Service2,HomeControl类创建类型由Container容器来创建,感觉IOC与MVC已经完美结合了,但是运行以后就碰到了阻力。

 缺少一个IControllerFactory类,缺少类型映射。

正如dudu所说我们总不能MVC中的所有接口都要注册一下,所以我们需要知道什么时候接受创建Controller,当Contorller所有准备都完成后,我们才接受创建Controller

   public class UnityControllerFactory : DefaultControllerFactory
    {
        protected override IController GetControllerInstance(System.Web.Routing.RequestContext requestContext, Type controllerType)
        {
            return (IController)HttpContainerBuilder.UnityContainer.Resolve(controllerType);
        }

    }

 这样我们在获取Controller时才从容器中解析对象,但是我们如果将那些没有在容器中注册过的类,实例化交给MVC自己实例

     public object GetService(Type serviceType)
        {
            if (container.IsRegistered(serviceType))
            {
                return container.Resolve(serviceType);
            }
            return null;
        }

当依赖解析器发现此类型没有注册过,就返回null,这样此类型的实例还有默认实例方式进行实例。 

综上就可以将IOC与MVC完美结合了,总结如下:

1.UnityContainner      通过方法RegisterType(Type)  注册类型

2.UnityDependecyResolver:IDenpendecySolve

    定义依赖解析的方式,可以指定给MVC

3.DependencyResolver.setResolver(第二点对象)    设置MVC依赖解析器

4.GetService(Type type)

获取解析对象,判断类型是否已注册  containner.IsRegistered(Type type),若没有注册,就返回null,还是采用默认获取对象方式

5.UnityControllerFactory:DefaultControllerFactory

重写GetControllerInstance(),将其从容器中获取对象

如何保证容器中在一次Http请求中保证只有一个对象,所以要LifetimeManager(生命周期策略)

 这个下次再讲。

 

  • Autofac(推荐)

        Autofac在使用中发现,他比Unity更贴切MVC

       下载地址:http://code.google.com/p/autofac/downloads/list

       Autofac.dll  基础包

        Autofac.Integration.Mvc.dll  MVC包

 //注册数据库访问对象
            ContainerBuilder.RegisterType(contextType).InstancePerHttpRequest();
            //注册Service对象
            ContainerBuilder.RegisterAssemblyTypes(serviceAssembly).InstancePerHttpRequest();
            //注册仓储类
            ContainerBuilder.RegisterAssemblyTypes(repositoryAssembly).InstancePerHttpRequest();


            //注册Mvc控制器
            ContainerBuilder.RegisterControllers(webAssembly).InstancePerHttpRequest();
            //注册Mvc模型绑定管道
            ContainerBuilder.RegisterModelBinderProvider();
            //注册Mvc模型绑定器
            ContainerBuilder.RegisterModelBinders();

            Container = ContainerBuilder.Build();
            //Contoler的MVC解析点通过Container
            DependencyResolver.SetResolver(new AutofacDependencyResolver(Container));

InstancePerHttpRequest:保证了生命周期策略,每次Http请求只实例化一次

RegisterControllers:提供了单独注册Controller的方法