ASP.NET MVC 4 相依性插入
此實際操作實驗室假設您具備 ASP.NET MVC 和 ASP.NET MVC 4 篩選器的基本知識。 如果您之前尚未使用 過 ASP.NET MVC 4 篩選 條件,建議您 ASP.NET MVC 自定義動作篩選 實際操作實驗室。
注意
所有範例程式代碼和代碼段都包含在 Web Camp 訓練套件中,可從 Microsoft-Web/WebCampTrainingKit 版本取得。 此實驗室專屬的專案可在MVC 4相依性插入 ASP.NET 取得。
在 面向物件程式設計 範例中,物件會在有參與者和取用者的共同作業模型中共同作業。 自然地,此通訊模型會產生物件和元件之間的相依性,在複雜度增加時變得難以管理。
類別相依性和模型複雜度
您可能已了解 處理站模式 和使用服務來區分介面與實作,其中客戶端物件通常會負責服務位置。
相依性插入模式是控件反轉的特定實作。 Control 反轉 (IoC) 表示物件不會建立其他物件,而它們依賴這些對象來執行其工作。 相反地,他們會從外部來源取得所需的物件(例如 xml 組態檔)。
相依性插入 (DI) 表示這是在沒有物件介入的情況下完成的,通常是由傳遞建構函式參數和設定屬性的架構元件所完成。
相依性插入 (DI) 設計模式
概括而言,相依性插入的目標是客戶端類別(例如 高爾夫球手)需要滿足介面的東西(例如 IClub)。 它並不在乎混凝土類型是什麼(如 WoodClub、IronClub、WedgeClub 或 PutterClub),它希望其他人處理這一點(例如一個很好的球童)。 ASP.NET MVC 中的相依性解析程式可讓您在其他地方註冊相依性邏輯(例如容器或 俱樂部袋)。
相依性插入 - 高爾夫類比
使用相依性插入模式和控件反轉的優點如下:
- 減少類別結合
- 增加重複使用程序代碼
- 改善程式代碼維護性
- 改善應用程式測試
注意
相依性插入有時會與抽象處理站設計模式進行比較,但兩種方法之間稍有差異。 DI 有一個架構可藉由呼叫 Factory 和已註冊的服務來解決相依性。
既然您已瞭解相依性插入模式,您將在整個實驗室中瞭解如何在MVC 4 ASP.NET 套用它。 您將開始使用控制器中的相依性插入來包含資料庫存取服務。 接下來,您會將相依性插入套用至 檢視 ,以取用服務並顯示資訊。 最後,您會將 DI 擴充至 ASP.NET MVC 4 篩選,並在解決方案中插入自定義動作篩選。
在此實際操作實驗室中,您將瞭解如何:
- 使用 NuGet 套件整合 ASP.NET MVC 4 與 Unity 以進行相依性插入
- 在 ASP.NET MVC控制器內使用相依性插入
- 在 ASP.NET MVC 檢視中使用相依性插入
- 在 ASP.NET MVC 動作篩選內使用相依性插入
注意
此實驗室使用 Unity.Mvc3 NuGet 套件進行相依性解析,但可以調整任何相依性插入架構來處理 ASP.NET MVC 4。
必要條件
您必須有下列專案才能完成此實驗室:
- Microsoft Visual Studio Express 2012 for Web 或更上層版本 (如需如何安裝它的指示,請參閱 附錄 A )。
設定
安裝程式碼片段
為方便起見,您將在本實驗中管理的大部分程式碼都以 Visual Studio 程式碼片段的形式提供。 若要安裝程式碼片段,請執行 .\Source\Setup\CodeSnippets.vsi 檔案。
如果您不熟悉 Visual Studio 代碼段,而且想要瞭解如何使用這些代碼段,您可以參閱本檔中的附錄「附錄 B:使用代碼段」。
練習
此實際操作實驗室是由下列練習所組成:
注意
每個練習都附有一個 End 資料夾,其中包含完成練習後應獲得的結果解決方案。 如果您需要其他幫助來完成練習,您可以使用此解決方案作為指南。
完成此實驗室的估計時間: 30 分鐘。
練習 1:插入控制器
在本練習中,您將瞭解如何使用 NuGet 套件整合 Unity,在 ASP.NET MVC 控制器中使用相依性插入。 因此,您會在MvcMusicStore控制器中包含服務,以將邏輯與數據存取區分開。 服務會在控制器建構函式中建立新的相依性,這會使用 Unity 的相依性插入來解析。
此方法將說明如何產生較少結合的應用程式,這些應用程式更有彈性且更容易維護和測試。 您也將瞭解如何整合 ASP.NET MVC 與 Unity。
關於 StoreManager 服務
開始解決方案中提供的MVC音樂市集現在包含一項服務,可管理名為 StoreService 的市集控制器數據。 您會在下方找到市集服務實作。 請注意,所有方法都會傳回 Model 實體。
namespace MvcMusicStore.Controllers
{
using System.Web.Mvc;
using MvcMusicStore.Filters;
using MvcMusicStore.Services;
[MyNewCustomActionFilter(Order = 1)]
[CustomActionFilter(Order = 2)]
public class StoreController : Controller
{
private IStoreService service;
public StoreController(IStoreService service)
{
this.service = service;
}
// GET: /Store/
public ActionResult Details(int id)
{
var album = this.service.GetAlbum(id);
if (album == null)
{
return this.HttpNotFound();
}
return this.View(album);
}
public ActionResult Browse(string genre)
{
// Retrieve Genre and its Associated Albums from database
var genreModel = this.service.GetGenreByName(genre);
return this.View(genreModel);
}
public ActionResult Index()
{
var genres = this.service.GetGenres();
return this.View(genres);
}
// GET: /Store/GenreMenu
public ActionResult GenreMenu()
{
var genres = this.service.GetGenres();
return this.PartialView(genres);
}
}
}
Begin 解決方案中的 StoreController 現在會取用 StoreService。 所有數據參考都已從 StoreController 中移除,現在可以修改目前的數據存取提供者,而不需要變更任何取用 StoreService 的方法。
您會發現 StoreController 實作與類別建構函式內的 StoreService 具有相依性。
注意
本練習中引進的相依性與控制反轉 (IoC) 相關。
StoreController 類別建構函式會接收 IStoreService 類型參數,這對於從 類別內部執行服務呼叫至關重要。 不過, StoreController 不會實作任何控制器都必須使用 ASP.NET MVC 的預設建構函式(不含任何參數)。
若要解析相依性,控制器必須由抽象處理站建立(類別會傳回指定型別的任何物件)。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using MvcMusicStore.ViewModels;
using MvcMusicStore.Models;
using MvcMusicStore.Services;
namespace MvcMusicStore.Controllers
{
public class StoreController : Controller
{
private IStoreService service;
public StoreController(IStoreService service)
{
this.service = service;
}
//
// GET: /Store/
public ActionResult Index()
{
// Create list of genres
var genres = this.service.GetGenreNames();
// Create your view model
var viewModel = new StoreIndexViewModel
{
Genres = genres.ToList(),
NumberOfGenres = genres.Count()
};
return View(viewModel);
}
//
// GET: /Store/Browse?genre=Disco
public ActionResult Browse(string genre)
{
var genreModel = this.service.GetGenreByName(genre);
var viewModel = new StoreBrowseViewModel()
{
Genre = genreModel,
Albums = genreModel.Albums.ToList()
};
return View(viewModel);
}
//
// GET: /Store/Details/5
public ActionResult Details(int id)
{
var album = this.service.GetAlbum(id);
return View(album);
}
}
}
注意
當 類別嘗試建立 StoreController 而不傳送服務物件時,您會收到錯誤,因為未宣告無參數建構函式。
工作 1 - 執行應用程式
在這項工作中,您將執行 Begin 應用程式,其中包含服務到市集控制器,以分隔數據存取與應用程式邏輯。
執行應用程式時,您會收到例外狀況,因為控制器服務預設不會傳遞為參數:
開啟 Source\Ex01-Injecting Controller\Begin 中的 Begin 方案。
您必須先下載一些遺漏的 NuGet 套件,才能繼續。 為此,請按一下專案功能表並選擇管理 NuGet 套件。
在管理 NuGet 套件對話方塊中,按一下還原以下載遺失的套件。
最後,透過點擊 Build | Build Solution 來建立解決方案。
注意
使用 NuGet 的優點之一是您不必交付專案中的所有程式庫,從而減少了專案大小。 使用 NuGet Power Tools,透過在 Packages.config 檔案中指定套件版本,您將能夠在第一次執行專案時下載所有必要的程式庫。 這就是為什麼您在從本實驗室打開現有解決方案後必須執行這些步驟的原因。
按 Ctrl + F5 執行應用程式而不偵錯。 您會收到錯誤訊息「沒有為此物件定義的無參數建構函式」:
執行 ASP.NET MVC Begin 應用程式時發生錯誤
關閉瀏覽器。
在下列步驟中,您將使用音樂市集解決方案來插入此控制器所需的相依性。
工作 2 - 將 Unity 納入 MvcMusicStore 解決方案
在這項工作中,您會將 Unity.Mvc3 NuGet 套件納入解決方案。
注意
Unity.Mvc3 套件是針對 ASP.NET MVC 3 所設計,但與 ASP.NET MVC 4 完全相容。
Unity 是輕量型、可延伸的相依性插入容器,可選擇性地支持實例和類型攔截。 它是一般用途的容器,可用於任何類型的 .NET 應用程式。 它提供相依性插入機制中找到的所有常見功能,包括:物件建立、在運行時間指定相依性和彈性來指定需求抽象化,方法是將元件組態延遲至容器。
在MvcMusicStore專案中安裝 Unity.Mvc3 NuGet 套件。 若要這樣做,請從 [檢視 | 其他 Windows] 開啟 [封裝管理員 控制台]。
執行下列命令。
PMC
Install-Package Unity.Mvc3
安裝 Unity.Mvc3 NuGet 套件
安裝 Unity.Mvc3 套件之後,請流覽它自動新增的檔案和資料夾,以簡化 Unity 設定。
已安裝 Unity.Mvc3 套件
工作 3 - 在 Global.asax.cs Application_Start 中註冊 Unity
在這項工作中,您將更新位於 Global.asax.cs 中的 Application_Start 方法,以呼叫 Unity Bootstrapper 初始化表達式,然後更新註冊要用於相依性插入之服務和控制器的啟動載入器檔案。
現在,您將連結啟動載入器,這是初始化 Unity 容器和相依性解析程序的檔案。 若要這樣做,請開啟 Global.asax.cs,並在 Application_Start 方法中新增下列醒目提示的程序代碼。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex01 - 初始化 Unity)
protected void Application_Start() { AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); Bootstrapper.Initialise(); AppConfig.Configure(); }
開啟 Bootstrapper.cs 檔案。
包含下列命名空間: MvcMusicStore.Services 和 MusicStore.Controllers。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex01 - 啟動載入器新增命名空間)
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc3; using MvcMusicStore.Services; using MvcMusicStore.Controllers;
以下列程序代碼取代 BuildUnityContainer 方法的內容,以註冊市集控制器和市集服務。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex01 - 註冊存放區控制器和服務)
private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.RegisterType<IStoreService, StoreService>(); container.RegisterType<IController, StoreController>("Store"); return container; }
工作 4 - 執行應用程式
在這項工作中,您將執行應用程式,以確認它現在可以在包含 Unity 之後載入。
按 F5 執行應用程式,應用程式現在應該會載入,而不會顯示任何錯誤訊息。
使用相依性插入執行應用程式
流覽至 /Store。 這會叫用現在使用 Unity 建立的 StoreController。
MVC 音樂市集
關閉瀏覽器。
在下列練習中,您將瞭解如何擴充相依性插入範圍,以在 ASP.NET MVC 檢視和動作篩選內使用它。
練習 2:插入檢視
在本練習中,您將瞭解如何在檢視中使用相依性插入,以及 unity 整合 ASP.NET MVC 4 的新功能。 若要這樣做,您將呼叫市集瀏覽檢視內的自定義服務,其會顯示訊息和下圖。
然後,您將整合專案與 Unity,並建立自定義相依性解析程式來插入相依性。
工作 1 - 建立取用服務的檢視
在這項工作中,您將建立檢視來執行服務呼叫以產生新的相依性。 此服務是由此解決方案中包含的簡單傳訊服務所組成。
開啟 Source\Ex02-Injecting View\Begin 資料夾中的 Begin 方案。 否則,您可以繼續使用完成上一個練習所獲得的 End 解決方案。
如果您開啟了提供的 Begin 解決方案,則需要先下載一些缺少的 NuGet 包,然後才能繼續。 為此,請按一下專案功能表並選擇管理 NuGet 套件。
在管理 NuGet 套件對話方塊中,按一下還原以下載遺失的套件。
最後,透過點擊 Build | Build Solution 來建立解決方案。
注意
使用 NuGet 的優點之一是您不必交付專案中的所有程式庫,從而減少了專案大小。 使用 NuGet Power Tools,透過在 Packages.config 檔案中指定套件版本,您將能夠在第一次執行專案時下載所有必要的程式庫。 這就是為什麼您在從本實驗室打開現有解決方案後必須執行這些步驟的原因。
如需詳細資訊,請參閱這篇文章: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages。
包含 /Services 中 [來源 \Assets] 資料夾中的 MessageService.cs 和 IMessageService.cs 類別。 若要這樣做,請以滑鼠右鍵按兩下 [服務 ] 資料夾,然後選取 [ 新增現有專案]。 流覽至檔案的位置並加以包含。
新增訊息服務和服務介面
注意
IMessageService 介面會定義 MessageService 類別所實作的兩個屬性。 這些屬性 -Message 和 ImageUrl- 會儲存要顯示之影像的訊息和 URL。
在專案的根資料夾中建立 /Pages 資料夾,然後從Source\Assets新增現有的類別MyBasePage.cs。 您將繼承自的基底頁面具有下列結構。
namespace MvcMusicStore.Pages { using System; using System.Collections.Generic; using System.Linq; using System.Web; using Microsoft.Practices.Unity; using MvcMusicStore.Models; using MvcMusicStore.Services; public class MyBasePage : System.Web.Mvc.WebViewPage<Genre> { [Dependency] public IMessageService MessageService { get; set; } public override void Execute() { } } }
從 /Views/Store 資料夾開啟 Browse.cshtml 檢視,並使它繼承自 MyBasePage.cs。
@inherits MvcMusicStore.Pages.MyBasePage @{ ViewBag.Title = "Browse Albums"; }
在 [流覽] 檢視中,新增 MessageService 的呼叫,以顯示服務所擷取的影像和訊息。 (C#)
@inherits MvcMusicStore.Pages.MyBasePage @{ Viewbag.Title = "Browse Albums"; } <div> @this.MessageService.Message <br /> <img alt="@this.MessageService.Message" src="@this.MessageService.ImageUrl" /> </div> ...
工作 2 - 包含自訂相依性解析程式和自定義檢視頁面啟動程式
在上一個工作中,您已在檢視中插入新的相依性,以在檢視內執行服務呼叫。 現在,您將藉由實作 ASP.NET MVC 相依性插入介面 IViewPageActivator 和 IDependencyResolver 來解決該相依性。 您會在解決方案中包含 IDependencyResolver 的實作,以使用 Unity 來處理服務擷取。 然後,您將包含另一個 IViewPageActivator 介面的自定義實作,以解決檢視的建立。
注意
由於 ASP.NET MVC 3,相依性插入的實作已簡化介面來註冊服務。 IDependencyResolver 和 IViewPageActivator 是相依性插入 ASP.NET MVC 3 功能的一部分。
- IDependencyResolver 介面會取代先前的 IMvcServiceLocator。 IDependencyResolver 的實作者必須傳回服務或服務集合的實例。
public interface IDependencyResolver {
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
- IViewPageActivator 介面可讓您更精細地控制如何透過相依性插入具現化檢視頁面。 實 作 IViewPageActivator 介面的類別可以使用內容資訊來建立檢視實例。
public interface IViewPageActivator {
object Create(ControllerContext controllerContext, Type type);
}
在專案的根資料夾中建立 /Factoryies 資料夾。
從 /Sources/Assets/ 到 Factoryies 資料夾,包含解決方案CustomViewPageActivator.cs。 若要這樣做,請以滑鼠右鍵按兩下 /Factoryies 資料夾,選取 [ 新增] |現有的專案 ,然後選取 [CustomViewPageActivator.cs]。 這個類別會實作 IViewPageActivator 介面來保存 Unity 容器。
namespace MvcMusicStore.Factories { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Practices.Unity; public class CustomViewPageActivator : IViewPageActivator { private IUnityContainer container; public CustomViewPageActivator(IUnityContainer container) { this.container = container; } public object Create(ControllerContext controllerContext, Type type) { return this.container.Resolve(type); } } }
注意
CustomViewPageActivator 負責使用 Unity 容器管理檢視的建立。
將UnityDependencyResolver.cs檔案從 /Sources/Assets 包含至 /Factoryies 資料夾。 若要這樣做,請以滑鼠右鍵按兩下 /Factoryies 資料夾,選取 [ 新增] |現有的專案 ,然後選取 [UnityDependencyResolver.cs 檔案]。
namespace MvcMusicStore.Factories { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Practices.Unity; public class UnityDependencyResolver : IDependencyResolver { private IUnityContainer container; private IDependencyResolver resolver; public UnityDependencyResolver(IUnityContainer container, IDependencyResolver resolver) { this.container = container; this.resolver = resolver; } public object GetService(Type serviceType) { try { return this.container.Resolve(serviceType); } catch { return this.resolver.GetService(serviceType); } } public IEnumerable<object> GetServices(Type serviceType) { try { return this.container.ResolveAll(serviceType); } catch { return this.resolver.GetServices(serviceType); } } } }
注意
UnityDependencyResolver 類別是 Unity 的自定義 DependencyResolver。 在 Unity 容器內找不到服務時,會叫用基底解析程式。
在下列工作中,這兩個實作都會註冊,讓模型知道服務和檢視的位置。
工作 3 - 在 Unity 容器中註冊相依性插入
在這項工作中,您會將所有先前的所有專案放在一起,讓相依性插入能夠運作。
到目前為止,您的解決方案具有下列元素:
- 繼承自 MyBaseClass 並取用 MessageService 的瀏覽檢視。
- 中繼類別 -MyBaseClass- 已針對服務介面宣告相依性插入。
- 服務 - MessageService - 及其介面 IMessageService。
- Unity - Unity 的自定義相依性解析程式 - UnityDependencyResolver - 可處理服務擷取。
- 建立頁面的檢視頁面啟動器 - CustomViewPageActivator 。
若要插入 瀏覽 檢視,您現在會在 Unity 容器中註冊自定義相依性解析程式。
開啟 Bootstrapper.cs 檔案。
在 Unity 容器中註冊 MessageService 的實例,以初始化服務:
(代碼段 - ASP.NET 相依性插入實驗室 - Ex02 - 註冊訊息服務)
private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.RegisterType<IStoreService, StoreService>(); container.RegisterType<IController, StoreController>("Store"); container.RegisterInstance<IMessageService>(new MessageService { Message = "You are welcome to our Web Camps Training Kit!", ImageUrl = "/Content/Images/webcamps.png" }); //... }
新增MvcMusicStore.Factories 命名空間的 參考。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex02 - Factoryies 命名空間)
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc3; using MvcMusicStore.Services; using MvcMusicStore.Controllers; using MvcMusicStore.Factories;
將 CustomViewPageActivator 註冊為 Unity 容器中的檢視頁面啟動器:
(代碼段 - ASP.NET 相依性插入實驗室 - Ex02 - 註冊 CustomViewPageActivator)
private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.RegisterType<IStoreService, StoreService>(); container.RegisterType<IController, StoreController>("Store"); container.RegisterInstance<IMessageService>(new MessageService { Message = "You are welcome to our Web Camps Training Kit!", ImageUrl = "/Content/Images/webcamps.png" }); container.RegisterType<IViewPageActivator, CustomViewPageActivator>(new InjectionConstructor(container)); return container; }
以 UnityDependencyResolver 實例取代 ASP.NET MVC 4 預設相依性解析程式。 若要這樣做,請使用下列程式代碼取代 Initialize 方法內容:
(代碼段 - ASP.NET 相依性插入實驗室 - Ex02 - 更新相依性解析程式)
public static void Initialise() { var container = BuildUnityContainer(); DependencyResolver.SetResolver(new Unity.Mvc3.UnityDependencyResolver(container)); IDependencyResolver resolver = DependencyResolver.Current; IDependencyResolver newResolver = new Factories.UnityDependencyResolver(container, resolver); DependencyResolver.SetResolver(newResolver); }
注意
ASP.NET MVC 提供預設相依性解析程序類別。 若要使用自定義相依性解析程式作為我們為 Unity 建立的解析程式,必須取代此解析程式。
工作 4 - 執行應用程式
在這項工作中,您將執行應用程式以確認市集瀏覽器會取用服務,並顯示擷取的影像和訊息:
按 F5 執行應用程式。
單擊 [內容類型] 功能表中的 [岩石],並查看 MessageService 如何插入檢視,並載入歡迎訊息和影像。 在此範例中,我們會輸入 「Rock」:
MVC 音樂市集 - 檢視插入
關閉瀏覽器。
練習 3:插入動作篩選
在先前的實作實驗室 自定義動作篩選 中,您已使用篩選自定義和插入。 在本練習中,您將瞭解如何使用 Unity 容器插入相依性插入來插入篩選。 若要這樣做,您會將新增至音樂市集解決方案的自定義動作篩選,以追蹤網站的活動。
工作 1 - 在解決方案中包含追蹤篩選
在這項工作中,您將包含音樂市集中的自定義動作篩選來追蹤事件。 由於先前的實驗室「自定義動作篩選」中已處理自定義動作篩選概念,因此您只會從此實驗室的 Assets 資料夾中包含篩選類別,然後建立 Unity 的篩選提供者:
開啟 Source\Ex03 - Injecting Action Filter\Begin 資料夾中的 Begin 方案。 否則,您可以繼續使用完成上一個練習所獲得的 End 解決方案。
如果您開啟了提供的 Begin 解決方案,則需要先下載一些缺少的 NuGet 包,然後才能繼續。 為此,請按一下專案功能表並選擇管理 NuGet 套件。
在管理 NuGet 套件對話方塊中,按一下還原以下載遺失的套件。
最後,透過點擊 Build | Build Solution 來建立解決方案。
注意
使用 NuGet 的優點之一是您不必交付專案中的所有程式庫,從而減少了專案大小。 使用 NuGet Power Tools,透過在 Packages.config 檔案中指定套件版本,您將能夠在第一次執行專案時下載所有必要的程式庫。 這就是為什麼您在從本實驗室打開現有解決方案後必須執行這些步驟的原因。
如需詳細資訊,請參閱這篇文章: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages。
將TraceActionFilter.cs檔案從 /Sources/Assets 包含至 /Filters 資料夾。
namespace MvcMusicStore.Filters { using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; public class TraceActionFilter : IActionFilter { public void OnActionExecuted(ActionExecutedContext filterContext) { filterContext.HttpContext.Trace.Write("OnActionExecuted"); filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName); filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName); } public void OnActionExecuting(ActionExecutingContext filterContext) { filterContext.HttpContext.Trace.Write("OnActionExecuting"); filterContext.HttpContext.Trace.Write("Action " + filterContext.ActionDescriptor.ActionName); filterContext.HttpContext.Trace.Write("Controller " + filterContext.ActionDescriptor.ControllerDescriptor.ControllerName); } } }
注意
此自定義動作篩選會執行 ASP.NET 追蹤。 您可以檢查「ASP.NET MVC 4 本機和動態動作篩選」實驗室以取得更多參考。
將空類別 FilterProvider.cs 新增至 /Filters 資料夾中 的專案。
在 FilterProvider.cs 中新增 System.Web.Mvc 和 Microsoft.Practices.Unity 命名空間。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex03 - 篩選提供者新增命名空間)
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Mvc; using Microsoft.Practices.Unity; namespace MvcMusicStore.Filters { public class FilterProvider { } }
讓類別繼承自 IFilterProvider 介面。
namespace MvcMusicStore.Filters { public class FilterProvider : IFilterProvider { } }
在 FilterProvider 類別中新增 IUnityContainer 屬性,然後建立類別建構函式以指派容器。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex03 - 篩選提供者建構函式)
public class FilterProvider : IFilterProvider { private IUnityContainer container; public FilterProvider(IUnityContainer container) { this.container = container; } }
注意
篩選提供者類別建構函式未在 內建立 新的 物件。 容器會當做參數傳遞,而相依性會由 Unity 解決。
在 FilterProvider 類別中,從 IFilterProvider 介面實作 GetFilters 方法。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex03 - 篩選提供者 GetFilters)
public class FilterProvider : IFilterProvider { private IUnityContainer container; public FilterProvider(IUnityContainer container) { this.container = container; } public IEnumerable<Filter> GetFilters(ControllerContext controllerContext, ActionDescriptor actionDescriptor) { foreach (IActionFilter actionFilter in this.container.ResolveAll<IActionFilter>()) { yield return new Filter(actionFilter, FilterScope.First, null); } } }
工作 2 - 註冊和啟用篩選
在這項工作中,您將啟用網站追蹤。 若要這樣做,您會在 Bootstrapper.cs BuildUnityContainer 方法中註冊篩選條件,以開始追蹤:
開啟 位於專案根目錄中的 Web.config ,並在 System.Web 群組啟用追蹤追蹤。
<system.web> <trace enabled="true"/> <compilation debug="true" targetFramework="4.5">
在專案根目錄開啟 Bootstrapper.cs 。
新增MvcMusicStore.Filters命名空間的參考。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex03 - 啟動載入器新增命名空間)
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc3; using MvcMusicStore.Services; using MvcMusicStore.Controllers; using MvcMusicStore.Factories; using MvcMusicStore.Filters;
選取 BuildUnityContainer 方法,並在 Unity 容器中註冊篩選。 您必須註冊篩選提供者以及動作篩選。
(代碼段 - ASP.NET 相依性插入實驗室 - Ex03 - 註冊 FilterProvider 和 ActionFilter)
private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); //... container.RegisterInstance<IFilterProvider>("FilterProvider", new FilterProvider(container)); container.RegisterInstance<IActionFilter>("LogActionFilter", new TraceActionFilter()); return container; }
工作 3 - 執行應用程式
在這項工作中,您將執行應用程式,並測試自定義動作篩選器正在追蹤活動:
按 F5 執行應用程式。
單擊 [內容類型] 功能表中的 [ 岩石 ]。 如果您想要,您可以瀏覽至更多內容類型。
Music Store
流覽至 /Trace.axd 以查看 [應用程式追蹤] 頁面,然後按兩下 [ 檢視詳細數據]。
應用程式追蹤記錄檔
應用程式追蹤 - 要求詳細數據
關閉瀏覽器。
摘要
藉由完成此實際操作實驗室,您已瞭解如何使用 NuGet 套件整合 Unity,在 ASP.NET MVC 4 中使用相依性插入。 為了達成此目的,您已在控制器、檢視和動作篩選內使用相依性插入。
涵蓋下列概念:
- ASP.NET MVC 4 相依性插入功能
- 使用 Unity.Mvc3 NuGet 套件的 Unity 整合
- 控制器中的相依性插入
- 檢視中的相依性插入
- 動作篩選的相依性插入
附錄 A:安裝 Visual Studio Express 2012 for Web
您可以使用 Microsoft Web 平台安裝程式安裝 Microsoft Visual Studio Express 2012 for Web 或其他「Express」版本。 以下說明將引導您使用 Microsoft Web 平台安裝程式安裝 Visual studio Express 2012 for Web 所需的步驟。
移至 /iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169。 或者,如果您已安裝 Web Platform Installer,您可以開啟它,並搜尋產品「Visual Studio Express 2012 for Web with Windows Azure SDK」。
按一下立即安裝。 如果您沒有 Web 平台安裝程式,您將被重定向到首先下載並安裝它。
Web 平台安裝程式開啟後,按一下安裝開始安裝。
安裝 Visual Studio Express
閱讀所有產品的授權和條款,然後按一下我接受繼續。
接受授權條款
等待下載和安裝過程完成。
安裝進度
安裝完成後,按一下完成。
安裝完成
按一下退出關閉 Web 平台安裝程式。
若要開啟 Visual Studio Express for Web,請前往開始畫面並開始編寫 VS Express,然後按一下 VS Express for Web 圖格。
VS Express Web 圖格
附錄 B:使用代碼段
有了程式碼片段,您就可以輕鬆獲得所需的所有程式碼。 實驗文件會準確告訴您何時可以使用它們,如下圖所示。
使用 Visual Studio 程式碼片段將程式碼插入專案中
使用鍵盤新增代碼段 (僅限 C#)
- 將遊標置於要插入程式碼的位置。
- 開始輸入程式碼片段名稱 (不含空格或連字元)。
- 觀看 IntelliSense 顯示符合的片段名稱。
- 選擇正確的程式碼片段 (或繼續輸入,直到選擇整個程式碼片段的名稱)。
- 按兩次 Tab 鍵可將程式碼片段插入到遊標位置。
開始輸入片段名稱
按 Tab 鍵選擇已反白的片段
再按 Tab 鍵,片段將會展開
若要使用滑鼠新增代碼段 (C#、Visual Basic 和 XML) 1。 以滑鼠右鍵按一下要插入程式碼片段的位置。
- 選擇插入片段,然後選擇我的程式碼片段。
- 按一下從清單中選擇相關片段。
以滑鼠右鍵按一下要插入程式碼片段的位置,然後選擇插入片段
按一下從清單中選擇相關片段