|
马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
据说很厉害,甚至可以把C#也干掉^_^,不过也很复杂,本来C++已经够复杂的。有人甚至还提出把这个东东引进标准,我觉得基本上不可能的。
大概你会问ASP.NETMVC为何会爱上IoC?
相爱的来由经常很复杂,就像一首歌中所唱——“只为相遇那一个眼神”。
而ASP.NETMVC爱上IoC只为IoC能完成MVC把持器的依附注进。
上面是博客园雇用频道(job.cnblogs.com)所用的一个MVC把持器:
- publicclassEnterpriseController{protectedIJobService_jobService;protectedIEnterpriseService_enterpriseService;#regionConstructorspublicEnterpriseController(IJobServicejobService,IEnterpriseServiceenterpriseService){_jobService=jobService;_enterpriseService=enterpriseService;}#endregion}
复制代码 如下面的代码所示,有了IoC举行依附注进,就不必要在机关函数中专门创立对应于_jobService与_enterpriseService的实例。IoC容器会在运转时主动创立IJobService与IEnterpriseService的实例,并传送给EnterpriseController的机关函数。
就由于这一点,MVC就爱上了IoC。爱就这么复杂。
可是相爱简单,相处难。。。相处的过程当中总会碰到林林总总的成绩。。。以是幸运来自于你是不是能勉力办理这些成绩。
代码天下也一样,当我们让MVC与IoC相处时,就碰到了成绩。这里我们以IoC容器Unity为例,申明一下我们碰到的成绩与办理办法。
要想完成Controller的依附注进,就必要让IoC容器接受Controller的创立,而ASP.NETMVC3中供应的IDependencyResolver接口就为完成这个供应了大概。以是,我们起首创立一个完成IDependencyResolver接口的UnityDependencyResolver类,代码以下:
- publicclassUnityDependencyResolver:IDependencyResolver{IUnityContainercontainer;publicUnityDependencyResolver(IUnityContainercontainer){this.container=container;}publicobjectGetService(TypeserviceType){returncontainer.Resolve(serviceType);}publicIEnumerable<object>GetServices(TypeserviceType){returncontainer.ResolveAll(serviceType);}}
复制代码 UnityDependencyResolver的感化就是挪用IoC容器(这里是Unity)剖析响应范例的实例。创立了UnityDependencyResolver,我们还必要告知MVC用它举行剖析。在Global.asax的Application_Start()办法中增加以下代码:
- protectedvoidApplication_Start(){IUnityContainercontainer=newUnityContainer();DependencyResolver.SetResolver(newUnityDependencyResolver(container));}
复制代码 我们运转一下程序尝尝,呈现上面的毛病提醒:
Thecurrenttype,System.Web.Mvc.IControllerFactory,isaninterfaceandcannotbeconstructed.Areyoumissingatypemapping?
<br>
从下面的毛病信息能够剖析出,毛病是产生在挪用UnityDependencyResolver.GetService办法时。ASP.NETMVC在运转的时分必要失掉IControllerFactory的完成实例,然后用它往创立响应的把持器实例。假如不必IoC容器,MVC默许会创立DefaultControllerFactory的实例。如今用了IoC,MVC找不到IControllerFactory的完成实例(我们基本没有注册嘛),以是呈现下面的毛病。
为懂得决这个成绩,我们注册一下DefaultControllerFactory:
- container.RegisterType<IControllerFactory,DefaultControllerFactory>();
复制代码 持续运转程序,又呈现新的毛病:
Thecurrenttype,System.Web.Mvc.IControllerActivator,isaninterfaceandcannotbeconstructed.Areyoumissingatypemapping?
找不到IControllerActivator的完成实例,看来,创立Controller还必要这个东东。检察MVC的源代码发明IControllerActivator的默许完成是DefaultControllerActivator,但忧郁的是它居然是privateclass,没法注册它。别无选择,只能本人完成IControllerActivator,名叫CustomControllerActivator,代码以下:
- publicclassCustomControllerActivator:IControllerActivator{IControllerIControllerActivator.Create(System.Web.Routing.RequestContextrequestContext,TypecontrollerType){returnDependencyResolver.Current.GetService(controllerType)asIController;}}
复制代码 持续运转,又呈现新的毛病:
Thecurrenttype,System.Web.Mvc.IViewPageActivator,isaninterfaceandcannotbeconstructed.Areyoumissingatypemapping?
天哪!岂非MVC中的一切接口都要注册一下。。。
这时候,头脑里俄然闪出一个唆使牌:
<br>
因而,脚踩刹车,打了一把偏向盘,驶上了另外一条道——假如IoC容器中没有注册,不激发非常,而是前往null,让MVC用本人的体例去向理。
修正UnityDependencyResolver的GetService办法:
- publicobjectGetService(TypeserviceType){if(!this.container.IsRegistered(serviceType)){returnnull;}returncontainer.Resolve(serviceType);}
复制代码 并作废之前在IoC容器中对DefaultControllerFactory与CustomControllerActivator的注册。
持续运转,乐成!固然乐成,但泊车一看,本来兜了一个圈子,又回到了动身的中央。统统仍是交由MVC处置,IoC容器形同虚设,Controller的依附注进没法完成。假如这时候会见想依附注进的Controller(机关函数带有参数),会呈现上面的毛病提醒:
Noparameterlessconstructordefinedforthisobject.
固然回到原地,看上往没有行进一步,但实践上你已离方针更近一些(堆集了履历,下次行进速率会更快)。就像你追一个女孩子,费经心思,却被回绝,看似你的统统勉力付之流水,实践上她的心门已有点松动。。。这时候,你要有一种半途而废的精力,把丢失感扔到无影无踪,然后持续勉力,深信“精诚所至,无动于衷”。办理手艺成绩也是一样事理。
重头再来!浏览MVC的源代码,懂得MVC的哀求处置历程,看看MVC是在甚么中央创立Controller的实例的,然后看有无举措让IoC容器来接受。
MvcHandler.BeginProcessRequest->MvcHandler.ProcessRequestInit,呵呵,找到:
- factory=ControllerBuilder.GetControllerFactory();controller=factory.CreateController(RequestContext,controllerName);
复制代码 下面的代码中,factory的范例是IControllerFactory,ControllerBuilder.GetControllerFactory()的感化是猎取IControllerFactory的完成实例,而实践是经由过程挪用IDependencyResolver接口失掉的(我们之前完成的UnityDependencyResolver接受了IDependencyResolver接口)。但我们没有在IoC容器中注册IControllerFactory,实践是由MVC前往IControllerFactory的默许完成DefaultControllerFactory。从下面的代码还能够看出,Controller实例的创立是经由过程挪用IControllerFactory.CreateController()办法,以是,我们要在DefaultControllerFactory.CreateController()办法中寻觅线索,对应代码以下:
- publicvirtualIControllerCreateController(RequestContextrequestContext,stringcontrollerName){TypecontrollerType=GetControllerType(requestContext,controllerName);IControllercontroller=GetControllerInstance(requestContext,controllerType);returncontroller;}
复制代码 CreateController()又挪用了GetControllerInstance()失掉Controller的实例,进一步检察其代码:
- protectedinternalvirtualIControllerGetControllerInstance(RequestContextrequestContext,TypecontrollerType){returnControllerActivator.Create(requestContext,controllerType);}
复制代码 ControllerActivator的范例是IControllerActivator,之前也提到过,IControllerActivator的默许完成是DefaultControllerActivator,由此能够看出,Controller实例的创立是由DefaultControllerActivator完成的。我们要完成依附注进,就要由IoC容器来接受。
那怎样来接受呢?——重载DefaultControllerFactory的CreateController办法,将创立Controller实例的事情转交给IoC容器,代码以下:
- publicclassUnityControllerFactory:DefaultControllerFactory{IUnityContainercontainer;publicUnityControllerFactory(IUnityContainercontainer){this.container=container;}protectedoverrideIControllerGetControllerInstance(RequestContextreqContext,TypecontrollerType){returncontainer.Resolve(controllerType)asIController;}}
复制代码 然后在IoC容器中注册一下UnityControllerFactory:
- publicclassUnityDependencyResolver:IDependencyResolver{IUnityContainercontainer;publicUnityDependencyResolver(IUnityContainercontainer){this.container=container;}publicobjectGetService(TypeserviceType){returncontainer.Resolve(serviceType);}publicIEnumerable<object>GetServices(TypeserviceType){returncontainer.ResolveAll(serviceType);}}0
复制代码 然后,运转程序。。。工夫不负故意人,依附注进乐成,成绩办理!今后,MVC与IoC过上了幸运的生存。
<br>
小结
要完成ASP.NETMVC把持器的依附注进,我们必要:
1.完成IDependencyResolver接口并经由过程DependencyResolver.SetResolver告诉MVC,将部分范例实例剖析事情交由IoC容器来处置;
2.承继DefaultControllerFactory,重载GetControllerInstance办法,并经由过程IoC容器将之注册为IControllerFactory的完成。
完全示例代码下载
它有很多缺点的,有兴趣可以到网上去搜索一下。于是微软有发明了“下一代”C++:C++/CLI语言,这个可以解决在.NETFramework中,托管C++产生的问题。在《程序员》杂志上,lippman和李建中合作连载介绍了C++/CLI语言。 |
|