Using StructureMap with the ASP.NET MVC framework

來源:互聯網
上載者:User

 原文地址:http://www.bengtbe.com/blog/post/2009/02/27/Using-StructureMap-with-the-ASPNET-MVC-framework.aspx

Using StructureMap with the ASP.NET MVC framework

2009-02-27 星期五 作者:bengtbe

在這裡我要闡述的是怎麼用.net frameword 架構下的StructureMap這個類.  
在學習這個之間你需要對ASP.NET MVC架構,依賴注入和控制反轉有基本的瞭解。
這些技術也不只用於 StructureMap ,如果你喜歡這些,那麼你當然也用其它的DI/Ioc  工具了。

我們就用這個UserController 例子還說起,它有一個屬性IUserService 來調用控制層的服務,當

然IUserService 本身也會調用 IUserPepository 這個在資料層的方法。這個UserController 用

控制反轉來訪問IUserService ,這就是說這個UserService 類就是選用控制反轉來注入

UserController 執行個體化IUserService;
public class UserController : Controller
{
    private readonly IUserService m_UserService;
    public UserController(IUserService userService)
    {
        m_UserService = userService;
    }
    public ActionResult Edit(int id)
    {
        return View(m_UserService.GetById(id));
    }
}
這就叫容器注入,如果你就這樣寫而沒有寫其它的設定檔那麼你將得到如下的錯誤:
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
 No parameterless constructor defined for this object.

Description: An unhandled exception occurred during the execution of the current web

request. Please review the stack trace for more information about the error and where

it originated in the code.

Exception Details: System.MissingMethodException: No parameterless constructor defined

for this object.  
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
其實預設的,這個ASP.NET MVC framework 是需要一個建構函式的,一種方法是構造形式如下:
public UserController() : this(new UserService(new UserRepository()))
{
}
上面的代碼運行時就是調用這個來構造的。你要解決上錯的錯誤可以重寫這個建構函式,這種方式

叫Poor Man's Dependency Injection(不明智人選擇的次等辦法),如果知道DI/Ioc你會另有所選

.
上面的方法還有一個很大的缺點(這個我深有體會^^_^^)就是你把這個介面寫死了就是用

UserService 初始化 IUserService ,同理你也許用同樣的方法來處理 UserService 中的

UserRepository .這樣就把視圖層和資料層聯絡起來了。這時如果UserRepository 再有幾個屬性

的話,就有看頭了,好像那樣寫代碼寫醜了一點兒。。。

言歸正轉我們來用這個StructureMap 的ObjectFactory 來實現相同的效果吧,(初始化

IuserService)代碼如下:
public UserController() : this(ObjectFactory.GetInstance<IUserService>())
{
}
很簡單的代碼!這樣這個屬性就被初始化了,然而這時每個Controller 都要這樣才能達到效果,有

沒有更簡單的方法呢?讓我們來達到盡量簡化的目地。
ASP.NET MVC framework 用這個factory 參數來初始化controllers,還提供了一個基類
DefaultControllerFactory 讓你更加自由的初始化controller:
public class StructureMapControllerFactory : DefaultControllerFactory
{
    protected override IController GetControllerInstance(Type controllerType)
    {
        if(controllerType == null) return null;
        try
        {
            return ObjectFactory.GetInstance(controllerType) as Controller;
        }
        catch (StructureMapException)
        {
            System.Diagnostics.Debug.WriteLine(ObjectFactory.WhatDoIHave());
            throw;
        }
    }
}
當我們每次調用controller 時就會調用這個方法.上面這段代碼就是MstrutureMap的
ObjectFactory 來定製Controller的過程即使你的類中不只一個介面時也沒有關係,它會自動初始

化所有這種介面屬性;
現在我告訴你可以把這段代碼加入以 Global.asax.cs 當中當程式運行時就載入它。如下:
protected void Application_Start()
{
    RegisterRoutes(RouteTable.Routes);
    StructureMapConfiguration.Configure();
    ControllerBuilder.Current.SetControllerFactory(new
      StructureMapControllerFactory());
}
最後一行這是我們告訴framework用我們定製的factory來代替預設的。現在你可以把Constructor

初始化的參數去年了吧,讓StrutureMap來幫你.

StrutureMap的構造
看到上面代碼的第二行了嗎?它就是用來構造StrutureMap的。它會構建一個新的StrutureMap 不

需要xml來配置。
public class StructureMapConfiguration
{
    public static void Configure()
    {
        ObjectFactory.Initialize(InitializeStructureMap);
    }
    private static void InitializeStructureMap(IInitializationExpression x)
    {
        x.Scan(y =>
                   {
                      y.Assembly("MvcWithNHibernate.Repositories");
                       y.Assembly("MvcWithNHibernate.Services");
                      y.With<DefaultConventionScanner>();
                   }
            );

http://stackoverflow.com/questions/1183124/how-do-i-mock-httpresponsebase-end

    }
}
你可以學習一下DefaultConventionScanner的用法,這個 scanner 是用來記錄哪些介面對應哪些類

來初始化的。比如 UserService 用來初始化IUserService ,UserRepository 來初始化

IUserRepository。
總結:
在這裡我們介紹了如何在ASP.NET MVC framework.架構下用StructureMap,我也介紹了怎麼樣利用

controller factory 來簡化你的代碼,一般情況下,在一開始就應用 Objectfactory 利用這種方

法可以減少不少代碼。在這裡只是介紹了在controller 層應用Objectfactory (其他的地方也可

以用了);

我在上面也是簡單的寫了一些代碼,介紹了一些常見的應用,(以下不會翻譯了,大致意思是你還

可以控制介面和類對應關係)

 

(這個我已經試過很好用的,還發現了一點就是類的構造參數有介面的它會初始成註冊的方法,會優先調用有介面的初始化。但是沒有試如果有兩個以上有參數的它怎麼處理?我想應該按參數最多的那個初始化吧!還沒有試,有時間的話就去試一試。)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.