蒙在股里 发表于 2015-1-18 11:20:54

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语言。

简单生活 发表于 2015-1-20 20:51:55

ASP.NET可以无缝地与WYSIWYGHTML编辑器和其他编程工具(包括MicrosoftVisualStudio.NET)一起工作。这不仅使得Web开发更加方便,而且还能提供这些工具必须提供的所有优点,包括开发人员可以用来将服务器控件拖放到Web页的GUI和完全集成的调试支持。微软为ASP.net设计了这样一些策略:易于写出结构清晰的代码、代码易于重用和共享、可用编译类语言编写等等,目的是让程序员更容易开发出Web应用,满足计算向Web转移的战略需要。

柔情似水 发表于 2015-1-30 05:03:27

我的意思是.net好用,从功能上来说比JAVA强还是很明显的。

仓酷云 发表于 2015-1-30 10:08:31

通过这次激烈的讨论,我从大家身上学到了太多,开阔了眼界,不管是支持我的还是骂我的,都感谢你们。

莫相离 发表于 2015-2-1 18:53:46

但是目前在CGI中使用的最为广泛的是Perl语言。所以,狭义上所指的CGI程序一般都是指Perl程序,一般CGI程序的后缀都是.pl或者.cgi。

深爱那片海 发表于 2015-2-7 13:34:19

目前在微软的.net战略中新推出的ASP.net借鉴了Java技术的优点,使用CSharp(C#)语言作为ASP.net的推荐语言,同时改进了以前ASP的安全性差等缺点。但是,使用ASP/ASP.net仍有一定的局限性,因为从某种角度来说它们只能在微软的WindowsNT/2000/XP+IIS的服务器平台上良好运行(虽然像ChilliSoft提供了在UNIX/Linux上运行ASP的解决方案.

飘灵儿 发表于 2015-2-9 00:59:27

众所周知,Windows以易用而出名,也因此占据不少的服务器市场。

爱飞 发表于 2015-2-15 10:57:15

业务逻辑代码都不必做任何改动;继承性和多态性使得代码的可重用性大大提高,你可以通过继承已有的对象最大限度保护你以前的投资。并且C#和C++、Java一样提供了完善的调试/纠错体系。

乐观 发表于 2015-3-2 21:41:01

代码逻辑混乱,难于管理:由于ASP是脚本语言混合html编程,所以你很难看清代码的逻辑关系,并且随着程序的复杂性增加,使得代码的管理十分困难,甚至超出一个程序员所能达到的管理能力,从而造成出错或这样那样的问题。

小女巫 发表于 2015-3-11 06:35:19

asp.net空间的支持有:ASP.NET1.1/虚拟目录/MicrosoftFrontPage2000扩展/CDONTS,同时他的网站上也提供了Asp.net的使用详解和程序源代码,相信对使用ASP.NET编程的程序员来说会非常有用哦!

分手快乐 发表于 2015-3-17 22:44:39

HTML:当然这是网页最基本的语言,每一个服务器语言都需要它的支持,要学习,这个肯定是开始,不说了.

飘飘悠悠 发表于 2015-3-25 04:02:35

由于CGI程序每响应一个客户就会打开一个新的进程,所以,当有多个用户同时进行CGI请求的时候,服务器就会打开多个进程,这样就加重了服务器的负担,使服务器的执行效率变得越来越低下。
页: [1]
查看完整版本: ASP.NET编程:想爱简单,相处难:当ASP.NET MVC爱上IoC仓酷云