天天看點

.Net下MVC的應用(三)--Maverick.Net介紹

在有Maverick.Net(以下稱NMav)之前已經有Maverick(for Java)了,NMav和Maverick一樣是一個輕量級的MVC架構,說它是輕量是因為Maverick直奔主題,除了實作MVC模式以外沒有像Struts一樣定義一個龐大的Taglib庫那樣的枝枝葉葉。

NMav是一個完整的M—V-C,這一點不像UIP(詳細介紹看前章)。NMav在實作上展現它的精幹,具有比較強的靈活性,它提供了Xml和Page兩類View的支援,提供了幾類Controller(主要對Model的使用上的分),提供了基于Asp.net的Controller的支援(稱之為Asp頁面控制型)和基于URL請求總控的Controller的支援(稱之Dispatcher控制型)。

先來看看NMav的組成結構:

Controller--控制器,其支援四種控制:

       Throwaway:沒有Model類

FormUser:Model由使用者指定,就是說Model類(比如你定義了一個UserInfo使用者DTO,

如果包含了UserId  和Password的地字段),它通過public abstract object MakeForm(IControllerContext cctx) 一個抽象方法要求從此類繼承的Controller類實作其方法而獲得使用者定義的Model執行個體,比如這裡可以在MakeForm()方法中加上一句: return new UserInfo();,實作建立一個UserInfo的Model執行個體。

ThrowawayForm: Model就是本身,就是說此類Controller類同時包含了Model的資訊

把UserInfo的定義放到Controller類中,那就省了UserInfo這個類了。

ThrowawayFormUser:是ThrowawayForm和FormUser的結合,可以采用自己指定Model

類(重載MakeForm方法),也可以不做任何動作,就預設為Controller本身類。

View――視圖,有5種:

DocumentView:一般的View都為此類型

RedirectView:是重定向View類型,這跟一般的頁面重定向沒什麼差別,隻是它重定向到另一個Command而非頁面

NullView:什麼都不做;

TrivialView:這類view一般作為引導作用,如果比如本身的View沒有含有頁面,但

是隻要在外面加一個首頁面

        XmlSerializingView:是對Xml作為頁面呈現的一類View

Transform――頁面的外套,做為View中一個重要部分,Transform的引入為Asp.net下不能采用像Jsp中那樣使用Include指令包含進一個頁面提供了一個很好的思路。然而Transform是和Include指令的作用是朝方向相反的,它是把Page放到有Transform指定的View中去,Transform就是外套。當然外套也有兩套:DocumentTransform(一般頁面)和XsltTransform(Xml頁面)。

Command――就是一次調用頁面的操作指令,目前View的情況下,如果傳回不同下個View就會被Controller調用到下一個頁面。如果用過Struts的話這個就能很好了解了,似乎我這樣表達還是沒到點上,從下文的配置檔案中聯系起來看就很好了解了。

Configuration――配置以及配置讀取。

Dispatcher――這個在UIP中是沒有的,是派發器,頁面送出就到這裡來,然後它根據頁面傳過來的狀态上下文來分發請求到相關的Command,再調用合适的View來呈現,就是上文所說的總控(也不知道這樣說是否合适)。NMav通過Dispachter類來實作,Dispatcher是從IHttpHandler接口繼承的,是以它能在做為總控用,Dispatcher在整個NMav運作時隻有一個執行個體,并且存放在Application的變量Hashtable中。

Context――上下文,遞交請求資訊到Dispatcher,由 MaverickContext主要包含了Model,HttpContext以及Transform等資訊。

NMav對多語言的支援,從NMav的設計初衷來看隻要在View中指定如mode=”語言類别”,就表示此View對該語言的支援,那麼就可以通過相同的View名稱指定不同Path的頁面,而不用像每個頁面從資源檔案中去讀取不同語言的Label資訊,畢竟不同的語言對應着不同的使用習慣和不同的文化。(呵呵)

其它的要說的是NMav的靈活性還展現配置上,它可以由使用者自己去繼承實作自己的Factory,可以由這些Factory建立運作的對象執行個體。 是以,分析NMav的過程你能發現很多的Factory。

       這裡有必要對NMav的運作過程了解一下:

在采用“Dispatcher控制型”(見上文)時,NMav的運作過程是這樣的:在運作這種模式時,需要在IIS加入對檔案類型的支援,添加完成如擴充為.m的與aspnet_isapi.dll的配置後,再在web.config中添加httphandler支援(

<httpHandlers>

        <add verb="*" path="*.m" type="Maverick.Dispatcher, Maverick" />

</httpHandlers>

)。

在完成上面的配置後,在浏覽器上敲入如http://locahost/NMav/test.m,因為上面的配置以及Dispatcher從IHttphandler繼承的緣故,那麼Dispatcher就會獲得請求,Dispatcher先在Application緩存中找Dispatcher是否已經執行個體化的執行個體,如果沒有那麼會進行執行個體化一個Dispatcher,初次加載時從配置檔案中加載配置資訊,并且緩存起來。Dispatcher執行個體根據URL位址中的最後一個單詞來作為一個Command,這裡就是test,然後從的緩存中找到剛才從配置檔案中配置的對應Command――test,轉入對應的Command,然後調用Go()方法,在Go方法中Command調用Controller的Go()。在Controller的Go方法中會把頁面的參數資訊從HttpContext.Request.Params取出表單的輸入參數,通過一個反射方法以名字相同來對Model的相應字段指派,然後再根據得到的ViewName找到下一個view,轉入頁面的呈現,呈現過程中,會把外套一件一件穿上(這裡是一個遞歸調用)。上述的過程,并沒有調用頁面後端的CS類。這就是說NMav就是把Asp.Net頁面的CS類看作了Controller。但是,在這裡,如果,你還沿用事件驅動開發的習慣,那麼,這些事件将不會再被觸發,進而微軟衆多的Server控件對事件也無效了,Server控件沒用了!!!! 這個是一個後嚴重的後退。這就是所說的Asp.Net下的沖突問題,辛辛苦苦幾十年,又回到了解放前。(……※(×#※×(◎)

還好,NMav采用了另外一套過程即“Asp頁面控制型”(見上文),類ControllablePage是這種控制類型的唯一Controller,從Page繼承(Page也是從IHttpHandler繼承的,是以,Asp.Net的事件驅動除了又ViewState還要有IHttpHandler來截獲處理,才能遞交到Code-Behind的CS類中去),此方式下CS類還是直接作為Controller,但是這時就沒有了對Model的支援。在這種方式下,請求先被Page的CS類獲得,這時可以處理Server控件的事件,調用頁面是在頁面呈現時進行,ControllablePage重載了Render方法,這時再把請求交給Dispatcher,然後進行上面的過程。這種方法最大的缺點是沒有了對Model的支援,上下文包含的Model資訊再也不是model的資訊,而是頁面資訊。再者,在我個人喜好來看,十分希望Controller還是能和CS類分開,這樣的代碼才更清晰。

大緻說了一下NMav的運作過程,接下來我們還是用login的示例來講解一下配置檔案,以Dispatcher控制類型方式為例,假設有login.aspx,index.aspx,error.aspx,frame.aspx其cs類被殺了,有了一個myController的從FormUser繼承的類,那麼可以根據下面一組配置來實作一個登入成功到index頁面,index頁面還有一個Transform—frame.aspx,失敗到error(一般要停在登入頁面提示重新登入,這裡僅做例子)。

    public class myController:Maverick.Ctl.ThrowawayFormUser

    {

        //UserInfo 為自定義的DTO類

        private UserInfo theUser;

public myController(){

            }

        public override object MakeForm(Maverick.Flow.IControllerContext cctx)  {

            theUser=new UserInfo();

            return theUser;

            }

        protected override string Perform(){//這裡會被Go()方法調用

//這裡可以調用邏輯接口,此處簡化

if(theUser.UserId=="allen" && theUser.Password=="123")

                return "success";

            else

                return "fail";

        }

    }

Maverick.config的XML配置如下:

<?xml version="1.0"?> 

<maverick version="2.0" default-view-type="document" default-transform-type="document"> //default*預設類型

<views>//全局view

<view id="loginSuccess" path="index.aspx"> //這裡沒有type,采用default-view-type

            <transform path=" frame.aspx"/>   //外套

    </view>

        <!—定義更多view-->

    </views>

    <commands>

        <command name="login.m ">    //這在URL敲入

            <controller class="NMavTest1.Ctl.myController, NMavTest1"/> //Controller,如果隻有單個View可省略

            ///用全局View在上面的Views中定義

            ///也可以不用在全局View中定義,直接

            ///<view name="success" path="index.aspx ">

            ///      <transform path="frame.aspx"/>

            ///</view>

            <view name="success" ref=" loginSuccess ">//這裡使用了引用

            ///

            <view name="fail " type=”document” mode=”en” path="error.aspx" />//可以采用mode實作多語言

        </command>

        <!—command 此處可以添加更多command-->

    </commands>

</maverick>

在web.config配置加入Maverick配置節:

<configSections>

        <sectionGroup name="Maverick">

<section name="Dispatcher" type="System.Configuration.NameValueSectionHandler,system " />

        </sectionGroup>

    </configSections>

    <Maverick>

        <Dispatcher>

            <add key="configFile" value="maverick.config" /> //Maverick檔案位置

            <add key="reloadCommand" value="reload" />//reloadCommand名字,用來放置重新加載

            <add key="currentConfigCommand" value="currentConfig" /> //目前指令名字

            <add key="limitTransformsParam" value="maxTransforms" />//最大外套數

        </Dispatcher>

    </Maverick>

NMav在應該也是一個比較早(2003就已經釋出了1.1版)的一個.Net下的MVC實作,其實作是非常輕量的,而功能又是比較完備并展現出它的靈活行。如果我們反觀一下NMav,NMav在Asp.Net下的局限也是實實在在的,可以說NMav隻是Maverick從Java到.Net的一個翻版,并沒有考慮到Asp.Net的實際情況,它沒有考慮到Asp.Net事件驅動開發的特點以及.Net的運作機制,這樣的結果是直接導緻了Asp.net頁面上的Server控件不能用,起因是NMav和Page類根本上沖突了,加入進來的修補措施也是很粗糙的,連對Model的支援都沒有了,那這樣的還比不上UIP了。

NMav代碼的存放放組織不是很好,而且有些類并沒有太大的用處,上面提到的currentConfig和reloadCommand等,但是NMav整體上來看實作還是相當漂亮的。

繼續閱讀