ASP.NET MVC 3 RTM 更新(1)

來源:互聯網
上載者:User
一、路由(Routing)

路由功能最初整合在ASP.NET MVC(以下簡稱MVC)中,後來被獨立出來形成了System.Web.Routing 3.5程式集。ASP.NET 4已經把Routing功能已經轉移到了System.Web 4 程式集下作為基礎服務的一部分。在使用Routing功能時,您已不再需要在web.config中註冊Module,因為UrlRoutingModule已經整合進ASP.NET 4中了,就像FormsAuthenticationModule等Module一樣(C:\Windows\Microsoft.NET\Framework\v4.0.30319\Config\web.config 的httpModules節點)。而ASP.NET MVC 3(以下簡稱MVC3)是基於ASP.NET 4的。

在System.Web.Routing 3.5中,UrlRoutingModule通過處理PostResolveRequestCache和PostMapRequestHandler事件來配合佈建要求處理常式(IHttpHandler),而在System.Web.Routing 4中,只處理了PostResolveRequestCache事件(PostMapRequestHandler事件也處理了,但什麼都不做,但已標明到期)。

值得一提的是ASP.NET 4的HttpRequest新增加了一個RequestContext屬性,其類型正是System.Web.Routing.RequestContext。該類封裝了當前請求上下文以及RouteData。

增加了PageRouteHandler類以支援WebForm的路由功能,該類實現IRouteHandler介面。而在ASP.NET 2.0中,得自己實作類別似的IRouteHandler。
為了更方便的添加該類型的路由規則,RouteCollection類中還新增加了四個MapPageRoute的重載方法。

簡單示範一下:
1、建立一個基於.Net 4的Web Application。
2、建立Global.asa並修改Global.asa.cs的Application_Start方法
        void Application_Start(object sender, EventArgs e)
        {
            // 以下兩種方式都可以添加路由規則,顯然MapPageRoute更方便、清晰一些
            //RouteTable.Routes.Add("newRoute",new Route("TestRouting",new PageRouteHandler("~/TestRouting.aspx")));
            RouteTable.Routes.MapPageRoute("newRoute"
                , "RoutingTest"
                , "~/RoutingTest.aspx");
            
        }
3、建立Web表單,命名為RoutingTest.aspx。在裡面隨便輸入一些內容。
4、啟動調試(F5),輸入類似的網址:http://localhost:3232/RoutingTest

一切正常的話應該顯示出您輸入的內容。

二、IDependencyResolver和DependencyResolver

Ioc/DI(Inversion of Control / the Dependency Injection,控制反轉/依賴注入)是實現系統解耦的一大利器。.Net平台可用的DI容器有Castle Windsor、StructureMap、Autofac 、Unity等。在MVC2中我們就可以很容易的使用這些容器,MVC3在DI方面又為我們做了什麼呢?

需要清楚一點,MVC3對DI的支援並不是說它內建了類似於Autofac之類的DI容器。它只是內建了一種建立(擷取)對象的預設“方式”(DefaultDependencyResolver),這種“方式”內部其中一個途徑是通過Activator.CreateInstance(Type serviceType)來建立對象。更重要的是,它提供了一種API讓我們可以改變這種方式。這使得我們可以使用Autofac之類的DI方式來替換。

下面我們從源碼角度分析一下MVC3是如何?這種機制的。

首先看看IDependencyResolver介面,該介面正是上面所說的建立(擷取)對象的“方式”。介面有兩個方法,GetService根據Type擷取一個簡單對象,GetServices根據Type擷取一個集合對象。
public interface IDependencyResolver
{
    object GetService(Type serviceType);
    IEnumerable<object> GetServices(Type serviceType);
}
DependencyResolver並不是IDependencyResolver介面的實現。
它有兩個私人內聯類DefaultDependencyResolver和DelegateBasedDependencyResolver,都是現實的IDependencyResolver介面;
一個DependencyResover型的私人變數_instance;
一個IDependencyResolver型的私人變數_current;
一個靜態構造方法,方法內部建立一個DependencyResolver賦給_instance變數;
一個預設構造方法,方法內部建立一個DefaultDependencyResolver賦給_current變數;
兩個唯讀類型為IDependencyResolver的屬性Current和InnerCurrent,這兩個屬性的get方法最終返回的是_instance變數——典型的單例模式;
三個InnerSetResolver重載方法和三個SetResolver重載方法。每個SetResolver只是簡單的調用對應的InnerSetResolver方法。這些方法用於設定當前的IDependencyResolver對象,並將對象賦給_current變數。

當我們需要根據某種類型比如SomeClass建立相應的對象時,我們這樣調用:DependencyResolver.Current.GetService(typeof(SomeType))。
當然,返回結合對象就這樣調用DependencyResolver.Current.GetServices(typeof(SomeType))。
預設情況下我們使用的是DefaultDependencyResolver對象,在該對象的GetService方法內部,通過調用Activator.CreateInstance(typeof(SomeType))來建立對象,而GetServices方法返回的是numerable.Empty<object>()產生的對象。

IDependencyResolver介面是建立(擷取)對象的“方式”,而SetResolver方法等則是改變這種方式的API。下面簡單分析一下這幾個方法。
1、InnerSetResolver(IDependencyResolver resolver)
該方法接受一個IDependencyResolver型參數,方法內部直接將值賦給_current變數。
2、InnerSetResolver(Func<Type, object> getService, Func<Type, IEnumerable<object>> getServices)
該方法接受兩個委託,第一個接受一個Type型參數返回object型對象,而第二個返回IEnumerable<object>型集合對象。
方法內部建立一個DelegateBasedDependencyResolver對象。調用DelegateBasedDependencyResolver.GetService(Type type)返回的
是getService(type)的執行結果。相應的,調用GetServices(Type type)返回的是getServices(type)的執行結果。
3、InnerSetResolver(object commonServiceLocator)
該方法接受一個object型參數,方法內部會通過反射的方式嘗試擷取方法名為"GetInstance"和"GetAllInstances",參數為Type型的兩個方法;
接著檢查方法的傳回值是否分別是object型和IEnumeralbe<object>型,如果是建立一個DelegateBasedDependencyResolver對象,兩個方法作為構造方法
參數傳入,並將對象賦給_current變數。傳回值的不匹配則拋出異常。

您可能需要CommonServiceLocator的資料:http://commonservicelocator.codeplex.com

另外,DependencyResolverExtensions類是IDependencyResolver介面的擴充方法,分別是相應方法的泛型實現。
public static class DependencyResolverExtensions
{
    public static TService GetService<TService>(this IDependencyResolver resolver)
    {
        return (TService) resolver.GetService(typeof(TService));
    }

    public static IEnumerable<TService> GetServices<TService>(this IDependencyResolver resolver)
    {
        return resolver.GetServices(typeof(TService)).Cast<TService>();
    }
}

IDependencyResolver介面的實作類別中,通常採用面板模式。內部包含一個DI容器,當調用GetService或GetServices方法時,調用DI容器相應的方法。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.