ASP.NET编程:想爱简单,相处难:当ASP.NET MVC爱上IoC仓酷云
据说很厉害,甚至可以把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语言。 ASP.NET可以无缝地与WYSIWYGHTML编辑器和其他编程工具(包括MicrosoftVisualStudio.NET)一起工作。这不仅使得Web开发更加方便,而且还能提供这些工具必须提供的所有优点,包括开发人员可以用来将服务器控件拖放到Web页的GUI和完全集成的调试支持。微软为ASP.net设计了这样一些策略:易于写出结构清晰的代码、代码易于重用和共享、可用编译类语言编写等等,目的是让程序员更容易开发出Web应用,满足计算向Web转移的战略需要。 我的意思是.net好用,从功能上来说比JAVA强还是很明显的。 通过这次激烈的讨论,我从大家身上学到了太多,开阔了眼界,不管是支持我的还是骂我的,都感谢你们。 但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。 目前在微软的.net战略中新推出的ASP.net借鉴了Java技术的优点,使用CSharp(C#)语言作为ASP.net的推荐语言,同时改进了以前ASP的安全性差等缺点。但是,使用ASP/ASP.net仍有一定的局限性,因为从某种角度来说它们只能在微软的WindowsNT/2000/XP+IIS的服务器平台上良好运行(虽然像ChilliSoft提供了在UNIX/Linux上运行ASP的解决方案. 众所周知,Windows以易用而出名,也因此占据不少的服务器市场。 业务逻辑代码都不必做任何改动;继承性和多态性使得代码的可重用性大大提高,你可以通过继承已有的对象最大限度保护你以前的投资。并且C#和C++、Java一样提供了完善的调试/纠错体系。 代码逻辑混乱,难于管理:由于ASP是脚本语言混合html编程,所以你很难看清代码的逻辑关系,并且随着程序的复杂性增加,使得代码的管理十分困难,甚至超出一个程序员所能达到的管理能力,从而造成出错或这样那样的问题。 asp.net空间的支持有:ASP.NET1.1/虚拟目录/MicrosoftFrontPage2000扩展/CDONTS,同时他的网站上也提供了Asp.net的使用详解和程序源代码,相信对使用ASP.NET编程的程序员来说会非常有用哦! HTML:当然这是网页最基本的语言,每一个服务器语言都需要它的支持,要学习,这个肯定是开始,不说了. 由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。
页:
[1]