ASP.NET MVC 4 相依性插入

Web 擷取小組

下載 Web Training Kit

此實際操作實驗室假設您具備 ASP.NET MVCASP.NET MVC 4 篩選的基本知識。 如果您之前未使用 ASP.NET MVC 4 篩選 ,建議您 ASP.NET MVC 自訂動作篩選 實際操作實驗室。

注意

所有範例程式碼和程式碼片段都包含在 Web Training Kit 中,可從 Microsoft-Web/WebCampTrainingKit 版本取得。 此實驗室特定的專案可在 MVC 4 相依性插入 ASP.NET取得。

物件導向程式設計 範例中,物件會在共同作業模型中共同作業,其中有參與者和取用者。 自然地,此通訊模型會產生物件和元件之間的相依性,在複雜性增加時變得難以管理。

類別相依性和模型複雜度 類別

類別相依性和模型複雜度

您可能已經聽過 處理站模式 ,以及使用服務在介面與實作之間分隔,其中用戶端物件通常負責服務位置。

相依性插入模式是控制反轉的特定實作。 控制 (IoC 的反轉) 表示物件不會建立其他物件來執行其工作。 相反地,他們會從外部來源取得所需的物件 (例如 xml 組態檔) 。

相依性插入 (DI) 表示這是在沒有物件介入的情況下完成,通常是由傳遞建構函式參數和設定屬性的架構元件所完成。

相依性插入 (DI) 設計模式

概括而言,相依性插入的目標是用戶端類別 (例如 ,轉送器) 需要滿足介面 (的專案,例如 IClub) 。 它並不關心具體類型 (,例如 WoodClub、IronClub、WedgeClubPutterClub) ,它想要其他人處理該 (,例如良好的 步調) 。 ASP.NET MVC 中的相依性解析程式可讓您在其他地方註冊相依性邏輯 (,例如容器或 俱樂部) 包。

相依性插入圖

相依性插入 - 類比

使用相依性插入模式和控制反向的優點如下:

  • 減少類別結合
  • 增加重複使用程式碼
  • 改善程式碼可維護性
  • 改善應用程式測試

注意

相依性插入有時會與抽象處理站設計模式比較,但這兩種方法之間有些許差異。 DI 有一個架構,可藉由呼叫處理站和已註冊的服務來解決相依性。

現在您已瞭解相依性插入模式,您將在整個實驗室中瞭解如何在 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。

必要條件

您必須有下列專案才能完成此實驗室:

安裝程式

安裝程式碼片段

為了方便起見,您將在此實驗室中管理的大部分程式碼都可以作為 Visual Studio 程式碼片段使用。 若要安裝程式碼片段,請執行 .\Source\Setup\CodeSnippets.vsi 檔案。

如果您不熟悉Visual Studio Code程式碼片段,而且想要瞭解如何使用這些程式碼片段,您可以參閱本檔中的附錄「附錄 B:使用程式碼片段」。


Exercises

此Hands-On實驗室是由下列練習所組成:

  1. 練習 1:插入控制器
  2. 練習 2:插入檢視
  3. 練習 3:插入篩選

注意

每個練習都會伴隨 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);
        }
    }
}

從開始解決方案的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 應用程式,其中包含服務到存放區控制器,以分隔資料存取與應用程式邏輯。

執行應用程式時,您會收到例外狀況,因為控制器服務預設不會傳遞為參數:

  1. 開啟Source\Ex01-Injecting Controller\Begin中的Begin方案。

    1. 您必須先下載一些遺漏的 NuGet 套件,才能繼續。 若要這樣做,請按一下 [專案] 功能表,然後選取 [ 管理 NuGet 套件]。

    2. 在 [ 管理 NuGet 套件] 對話方塊中,按一下 [ 還原 ] 以下載遺漏的套件。

    3. 最後,按一下 [ | 置建置方案] 來建置方案。

      注意

      使用 NuGet 的其中一個優點是,您不需要寄送專案中的所有程式庫,以減少專案大小。 使用 NuGet Power Tools,藉由在 Packages.config 檔案中指定套件版本,您將能夠在第一次執行專案時下載所有必要的程式庫。 這就是您從此實驗室開啟現有解決方案之後,必須執行這些步驟的原因。

  2. Ctrl + F5 執行應用程式而不進行偵錯。 您將會收到錯誤訊息:「沒有為此物件定義的無參數建構函式」:

    執行 ASP.NET MVC Begin 應用程式時

    執行 ASP.NET MVC Begin 應用程式時發生錯誤

  3. 關閉瀏覽器。

在下列步驟中,您將使用音樂市集解決方案來插入此控制器所需的相依性。

工作 2 - 將 Unity 納入 MvcMusicStore 解決方案

在這項工作中,您會將 Unity.Mvc3 NuGet 套件包含在解決方案中。

注意

Unity.Mvc3 套件是專為 ASP.NET MVC 3 所設計,但與 ASP.NET MVC 4 完全相容。

Unity 是輕量型、可延伸的相依性插入容器,具有實例和類型攔截的選擇性支援。 它是一般用途的容器,可用於任何類型的 .NET 應用程式。 它提供相依性插入機制中找到的所有常見功能,包括:物件建立、在執行時間指定相依性和彈性來指定需求抽象概念,方法是將元件組態延遲至容器。

  1. MvcMusicStore專案中安裝Unity.Mvc3 NuGet 套件。 若要這樣做,請從[檢視 | 其他視窗] 開啟[套件管理員主控台]。

  2. 執行下列命令。

    PMC

    Install-Package Unity.Mvc3
    

    安裝 Unity.Mvc3 NuGet 套件

    安裝 Unity.Mvc3 NuGet 套件

  3. 安裝 Unity.Mvc3 套件之後,請流覽它自動新增的檔案和資料夾,以簡化 Unity 設定。

    已安裝 Unity.Mvc3 套件已安裝

    已安裝 Unity.Mvc3 套件

工作 3 - 在 Global.asax.cs 中註冊 Unity Application_Start

在這項工作中,您將更新位於 Global.asax.cs中的Application_Start方法,以呼叫 Unity 啟動載入器初始化運算式,然後更新註冊要用於相依性插入之服務和控制器的啟動載入器檔案。

  1. 現在,您將連結啟動載入器,這是初始化 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();
    }
    
  2. 開啟 Bootstrapper.cs 檔案。

  3. 包含下列命名空間: MvcMusicStore.ServicesMusicStore.Controllers

    (程式碼片段 - ASP.NET 相依性插入實驗室 - Ex01 - 啟動載入器新增命名空間)

    using System.Web.Mvc;
    using Microsoft.Practices.Unity;
    using Unity.Mvc3;
    using MvcMusicStore.Services;
    using MvcMusicStore.Controllers;
    
  4. 以下列程式碼取代 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 之後載入。

  1. F5 執行應用程式,應用程式現在應該會載入,而不會顯示任何錯誤訊息。

    使用相依性插入

    使用相依性插入執行應用程式

  2. 流覽至 /Store。 這會叫用 StoreController,其現在使用 Unity建立。

    MVC 音樂市集

    MVC 音樂市集

  3. 關閉瀏覽器。

在下列練習中,您將瞭解如何擴充相依性插入範圍,以在 MVC 檢視和動作篩選內 ASP.NET 使用它。

練習 2:插入檢視

在此練習中,您將瞭解如何在檢視中使用相依性插入,以及 Unity 整合 ASP.NET MVC 4 的新功能。 若要這樣做,您會在市集流覽檢視內呼叫自訂服務,其會顯示訊息和下圖。

然後,您會將專案與 Unity 整合,並建立自訂相依性解析程式來插入相依性。

工作 1 - 建立取用服務的檢視

在此工作中,您將建立檢視來執行服務呼叫以產生新的相依性。 此服務是由此解決方案中包含的簡單傳訊服務所組成。

  1. 開啟Source\Ex02-Injecting View\Begin資料夾中的Begin方案。 否則,您可以繼續使用完成上一個練習所取得的 結束 解決方案。

    1. 如果您開啟提供的 Begin 解決方案,您必須先下載一些遺漏的 NuGet 套件,才能繼續。 若要這樣做,請按一下 [專案] 功能表,然後選取 [ 管理 NuGet 套件]。

    2. 在 [ 管理 NuGet 套件] 對話方塊中,按一下 [ 還原 ] 以下載遺漏的套件。

    3. 最後,按一下 [建置建置方案] 來建 | 置方案。

      注意

      使用 NuGet 的其中一個優點是,您不需要寄送專案中的所有程式庫,進而減少專案大小。 使用 NuGet Power Tools,藉由在Packages.config檔案中指定套件版本,您就能夠在第一次執行專案時下載所有必要的程式庫。 這就是您從此實驗室開啟現有解決方案之後,必須執行這些步驟的原因。

      如需詳細資訊,請參閱這篇文章: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages

  2. /Services的 [來源 \Assets] 資料夾中包含MessageService.csIMessageService.cs類別。 若要這樣做,請以滑鼠右鍵按一下 [服務 ] 資料夾,然後選取 [ 新增現有專案]。 流覽至檔案的位置並加以包含。

    新增訊息服務和服務介面

    新增訊息服務和服務介面

    注意

    IMessageService介面會定義MessageService類別所實作的兩個屬性。 這些屬性 -MessageImageUrl- 會儲存要顯示之影像的訊息和 URL。

  3. 在專案的根資料夾中建立/Pages資料夾,然後從Source\Assets新增現有的類別 MyBasePage.cs。 您將繼承自的基底頁面具有下列結構。

    Pages 資料夾 Pages

    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()
            {
            }
        }
    }
    
  4. /Views/Store資料夾開啟Browse.cshtml檢視,並使它繼承自MyBasePage.cs

    @inherits MvcMusicStore.Pages.MyBasePage
    @{
         ViewBag.Title = "Browse Albums";
    }
    
  5. [流覽 ] 檢視中,新增 對 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 相依性插入介面 IViewPageActivatorIDependencyResolver來解決該相依性。 您將在解決方案中包含 IDependencyResolver 的實作,以使用 Unity 來處理服務擷取。 然後,您將包含另一個 IViewPageActivator 介面的自訂實作,以解決檢視的建立。

注意

由於 ASP.NET MVC 3,相依性插入的實作已簡化介面來註冊服務。 IDependencyResolverIViewPageActivator 是相依性插入 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);
}
  1. 在專案的根資料夾中建立 /Factories 資料夾。

  2. /Sources/Assets/CustomViewPageActivator.cs包含至解決方案至Factoryies資料夾。 若要這樣做,請以滑鼠右鍵按一下 /Factories 資料夾,選取 [ 新增] |現有的專案 ,然後選取 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 容器來管理檢視的建立。

  3. UnityDependencyResolver.cs 檔案從 /Sources/Assets 包含至 /Factories 資料夾。 若要這樣做,請以滑鼠右鍵按一下 /Factories 資料夾,選取 [ 新增] |現有的專案 ,然後選取 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 - UnityDependencyResolver 的自訂相依性解析程式,可處理服務擷取。
  • 建立頁面的檢視頁面啟動器 - CustomViewPageActivator

若要插入 流覽 檢視,您現在會在 Unity 容器中註冊自訂相依性解析程式。

  1. 開啟 Bootstrapper.cs 檔案。

  2. 在 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"
        });
        //...
    }
    
  3. 新增 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;
    
  4. 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;
    }
    
  5. 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 - 執行應用程式

在這項工作中,您將執行應用程式,以確認市集瀏覽器會取用服務,並顯示擷取的影像和訊息:

  1. F5 鍵執行應用程式。

  2. 按一下 [內容類型] 功能表中的 [岩石 ],並查看 MessageService 如何插入檢視,並載入歡迎訊息和影像。 在此範例中,我們會輸入 「Rock」:

    MVC 音樂市集 - 檢視插入

    MVC 音樂市集 - 檢視插入

  3. 關閉瀏覽器。

練習 3:插入動作篩選

在先前的Hands-On實驗室 自訂動作篩選 中,您已使用篩選自訂和插入。 在此練習中,您將瞭解如何使用 Unity 容器插入相依性插入來插入篩選。 若要這樣做,您會將新增至音樂市集解決方案的自訂動作篩選器,以追蹤網站的活動。

工作 1 - 在解決方案中包含追蹤篩選

在這項工作中,您會在音樂市集中包含自訂動作篩選來追蹤事件。 由於先前的實驗室「自訂動作篩選」中已處理自訂動作篩選概念,因此您只會從此實驗室的 Assets 資料夾包含篩選類別,然後建立 Unity 的篩選提供者:

  1. 開啟Source\Ex03 - Injecting Action Filter\Begin資料夾中的Begin方案。 否則,您可以繼續使用完成上一個練習所取得的 結束 解決方案。

    1. 如果您開啟提供的 Begin 解決方案,您必須先下載一些遺漏的 NuGet 套件,才能繼續。 若要這樣做,請按一下 [專案] 功能表,然後選取 [ 管理 NuGet 套件]。

    2. 在 [ 管理 NuGet 套件] 對話方塊中,按一下 [ 還原 ] 以下載遺漏的套件。

    3. 最後,按一下 [建置建置方案] 來建 | 置方案。

      注意

      使用 NuGet 的其中一個優點是,您不需要寄送專案中的所有程式庫,進而減少專案大小。 使用 NuGet Power Tools,藉由在Packages.config檔案中指定套件版本,您就能夠在第一次執行專案時下載所有必要的程式庫。 這就是您從此實驗室開啟現有解決方案之後,必須執行這些步驟的原因。

      如需詳細資訊,請參閱這篇文章: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages

  2. 來自 /Sources/Assets 的TraceActionFilter.cs檔案包含至/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 本機和動態動作篩選」實驗室以取得更多參考。

  3. 將空類別FilterProvider.cs新增至/Filters資料夾中的專案。

  4. FilterProvider.cs中新增System.Web.MvcMicrosoft.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
         {
         }
    }
    
  5. 讓類別繼承自 IFilterProvider 介面。

    namespace MvcMusicStore.Filters
    {
        public class FilterProvider : IFilterProvider
        {
        }
    }
    
  6. FilterProvider類別中新增IUnityContainer屬性,然後建立類別建構函式以指派容器。

    (程式碼片段 - ASP.NET 相依性插入實驗室 - Ex03 - 篩選提供者建構函 式)

    public class FilterProvider : IFilterProvider
    {
        private IUnityContainer container;
    
        public FilterProvider(IUnityContainer container)
        {
            this.container = container;
        }
    }
    

    注意

    篩選提供者類別建構函式不會在 內建立 新的 物件。 容器會當做參數傳遞,且 Unity 會解析相依性。

  7. 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 方法中註冊篩選準則,以開始追蹤:

  1. 開啟位於專案根目錄中 的Web.config ,並在 System.Web 群組啟用追蹤追蹤。

    <system.web>
        <trace enabled="true"/>
        <compilation debug="true" targetFramework="4.5">
    
  2. 在專案根目錄開啟 Bootstrapper.cs

  3. 新增 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;
    
  4. 選取 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 - 執行應用程式

在這項工作中,您將執行應用程式,並測試自訂動作篩選器是否正在追蹤活動:

  1. F5 鍵執行應用程式。

  2. 按一下 [內容類型] 功能表中的 [岩石 ]。 如果您想要,您可以流覽至更多內容類型。

    音樂市

    Music 市集

  3. 流覽至 /Trace.axd 以查看 [應用程式追蹤] 頁面,然後按一下 [ 檢視詳細資料]。

    應用程式追蹤記錄

    應用程式追蹤記錄檔

    應用程式追蹤 - 要求詳細

    應用程式追蹤 - 要求詳細資料

  4. 關閉瀏覽器。


摘要

藉由完成此Hands-On實驗室,您已瞭解如何使用 NuGet 套件整合 Unity,在 ASP.NET MVC 4 中使用相依性插入。 為了達到此目的,您已在控制器、檢視和動作篩選內使用相依性插入。

已涵蓋下列概念:

  • ASP.NET MVC 4 相依性插入功能
  • 使用 Unity.Mvc3 NuGet 套件的 Unity 整合
  • 控制器中的相依性插入
  • 檢視中的相依性插入
  • 動作篩選的相依性插入

附錄 A:安裝 Visual Studio Express 2012 for Web

您可以使用 Microsoft Web Platform Installer 安裝Microsoft Visual Studio Express 2012 for Web或其他「快速」版本。 下列指示會引導您使用Microsoft Web Platform Installer安裝Visual Studio Express 2012 for Web所需的步驟。

  1. 前往 https://go.microsoft.com/?linkid=9810169。 或者,如果您已安裝 Web Platform Installer,您可以開啟它,並使用Windows Azure SDK 搜尋產品「Visual Studio Express 2012 for Web」。

  2. 按一下 [ 立即安裝]。 如果您沒有 Web Platform Installer ,系統會將您重新導向以下載並先安裝。

  3. Web Platform Installer開啟之後,按一下 [安裝] 以啟動安裝程式。

    安裝 Visual Studio Express

    安裝Visual Studio Express

  4. 閱讀所有產品的授權和條款,然後按一下 [ 我接受 ] 繼續。

    接受授權條款

    接受授權條款

  5. 等候下載和安裝程式完成。

    安裝進度

    安裝進度

  6. 安裝完成時,按一下 [ 完成]。

    安裝已完成

    安裝已完成

  7. 按一下 [結束 ] 以關閉 Web Platform Installer。

  8. 若要開啟 web 的Visual Studio Express,請移至 [開始] 畫面並開始撰寫 「VS Express」,然後按一下[VS Express for Web] 圖格。

    VS Express for Web 圖格

    VS Express for Web 圖格

附錄 B:使用程式碼片段

使用程式碼片段時,您會有指尖所需的所有程式碼。 實驗室檔會告訴您何時可以使用它們,如下圖所示。

使用 Visual Studio 程式碼片段將程式碼插入專案中

使用 Visual Studio 程式碼片段將程式碼插入專案中

僅使用鍵盤 (C# 新增程式碼片段)

  1. 將游標放在您要插入程式碼的位置。
  2. 開始輸入程式碼片段名稱, (不含空格或連字號) 。
  3. 監看 IntelliSense 顯示相符的程式碼片段名稱。
  4. 選取正確的程式碼片段 (或持續輸入,直到選取整個程式碼片段的名稱) 為止。
  5. 按 Tab 鍵兩次,將程式碼片段插入游標位置。

開始輸入程式碼片段名稱 開始

開始輸入程式碼片段名稱

按 Tab 鍵選取醒目提示的程式碼片段

按 Tab 鍵以選取醒目提示的程式碼片段

再次按 Tab 鍵,程式碼片段會再次展開

再次按 Tab 鍵,程式碼片段將會展開

若要使用滑鼠 (C# 新增程式碼片段,Visual Basic 和 XML) 1. 以滑鼠右鍵按一下您要插入程式碼片段的位置。

  1. 選取 [插入程式碼片段 ],後面接著 [我的程式碼片段]。
  2. 按一下相關程式碼片段,從清單中挑選相關程式碼片段。

以滑鼠右鍵按一下您要插入程式碼片段的位置,然後選取 [插入程式碼片段] 以滑鼠

以滑鼠右鍵按一下您要插入程式碼片段的位置,然後選取 [插入程式碼片段]

從清單中挑選相關的程式碼片段,方法是按一下它

按一下相關程式碼片段,從清單中挑選相關的程式碼片段