ASP.NET MVC 4 依存関係挿入
このハンズオン ラボでは、ASP.NET MVC と ASP.NET MVC 4 フィルターに関する基本的な知識があることを前提としています。 これまでに ASP.NET MVC 4 フィルターを使用したことがない場合は、「ASP.NET MVC カスタム アクション フィルター」ハンズオン ラボを確認することをお勧めします。
Note
すべてのサンプル コードとスニペットは、Microsoft-Web/WebCampTrainingKit リリースから入手できる Web Camps トレーニング キットに含まれています。 このラボに固有のプロジェクトは、「ASP.NET MVC 4 依存関係挿入」で入手できます。
オブジェクト指向プログラミングのパラダイムでは、共同作成者とコンシューマーが存在するコラボレーション モデルでオブジェクトが連携します。 当然ながら、この通信モデルはオブジェクトとコンポーネント間に依存関係を生み出し、複雑さが増すと管理が難しくなります。
クラスの依存関係とモデルの複雑さ
ファクトリ パターンと、サービスを使用したインターフェイスと実装の分離について聞いたことがあるでしょう。この場合、多くのクライアント オブジェクトは、サービスの場所を担当します。
依存関係の挿入パターンは、制御の反転の特定の実装になります。 制御の反転 (IoC) は、オブジェクトが動作に使用する他のオブジェクトを作成しないことを意味します。 代わりに、外部ソース (xml 構成ファイルなど) から必要なオブジェクトを取得します。
依存関係の挿入 (DI) は、オブジェクトが介入することなく、通常はコンストラクター パラメーターと設定プロパティを渡すフレームワーク コンポーネントによって実行されることを意味します。
依存関係の挿入 (DI) の設計パターン
大まかに言えば、依存関係の挿入の目標は、クライアント クラス (例: ゴルファー) がインターフェイス (例: IClub) を満たすものを必要とすることです。 具体的な型 (例: WoodClub、IronClub、WedgeClub、PutterClub) に関係なく、他の誰か (例: 優れたキャディ) がこれを処理する必要があります。 ASP.NET MVC の依存関係リゾルバーを使用すると、依存関係ロジックを他の場所 (例: コンテナー、クラブ バッグ) に登録できます。
依存関係の挿入 - ゴルフの例え
依存関係の挿入パターンと制御の反転を使用することの利点は次のとおりです。
- クラス結合を削減できる
- コードの再利用が増える
- コードの保守性が向上する
- アプリケーション テストが向上する
Note
依存関係の挿入は、抽象ファクトリ設計パターンと比較されることがありますが、両方の方法には若干の違いがあります。 DI には、ファクトリと登録済みサービスを呼び出して依存関係を解決するために背後で動作するフレームワークが用意されています。
依存関係の挿入パターンを理解したところで、このラボでは ASP.NET MVC 4 で適用する方法について学習します。 データベース アクセス サービスを含めるには、コントローラーで依存関係の挿入の使用を開始します。 次に、依存関係の挿入をビューに適用して、サービスを使用し、情報を表示します。 最後に、DI を ASP.NET MVC 4 フィルターに拡張して、ソリューションにカスタム アクション フィルターを挿入します。
このハンズオン ラボでは、次の手順について学習します:
- NuGet パッケージを使用して、依存関係の挿入のために ASP.NET MVC 4 と Unity を統合する
- ASP.NET MVC コントローラー内で依存関係の挿入を使用する
- ASP.NET MVC ビュー内で依存関係の挿入を使用する
- ASP.NET MVC アクション フィルター内で依存関係の挿入を使用する
Note
このラボでは、依存関係の解決に Unity.Mvc3 NuGet パッケージを使用していますが、任意の依存関係の挿入フレームワークを、ASP.NET MVC 4 で動作するように調整できます。
前提条件
このラボを完了するには、次の項目が必要です:
- Microsoft Visual Studio Express 2012 for Web 以降 (インストール方法については「付録 A」を参照してください)。
段取り
コード スニペットのインストール
利便性のため、このラボで管理するコードの多くは、Visual Studio コード スニペットとして入手可能です。 コード スニペットをインストールするには、.\Source\Setup\CodeSnippets.vsi ファイルを実行します。
Visual Studio Code スニペットに慣れていない場合、その使用方法については、このドキュメントの付録「付録 B: コード スニペットの使用」を参照してください。
演習
このハンズオン ラボは、次の演習で構成されます:
Note
各演習には、演習を完了した後に得られる、結果のソリューションが含まれる End フォルダーが付帯しています。 このソリューションは、演習の作業についてさらにヘルプが必要な場合に、ガイドとして使用できます。
このラボの推定所要時間: 30 分。
演習 1: コントローラーの挿入
この演習では、NuGet パッケージを使用して Unity を統合し、ASP.NET MVC コントローラーで依存関係の挿入を使用する方法について学習します。 そのため、ロジックをデータ アクセスから分離するために、MvcMusicStore コントローラーにサービスを含めます。 サービスによってコントローラー コンストラクターに新しい依存関係が作成されます。これは、Unity の支援により依存関係の挿入を使用して解決されます。
この方法では、疎結合のアプリケーションを作成でき、柔軟性が高く、保守とテストを実施しやすくなります。 また、ASP.NET MVC を Unity と統合する方法についても学習します。
StoreManager サービスについて
Begin ソリューションで提供されている MVC Music Store に、Store Controller データを管理するサービスである StoreService が含まれるようになりました。 Store Service の実装を次に示します。 すべてのメソッドで 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 との依存関係があることを次に示します。
Note
この演習で紹介した依存関係は、制御の反転 (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);
}
}
}
Note
パラメーターなしのコンストラクターが宣言されていないため、クラスがサービス オブジェクトを送信せずに StoreController を作成しようとすると、エラーが発生します。
タスク 1 - アプリケーションの実行
このタスクでは、Begin アプリケーションを実行します。このアプリケーションでは、データ アクセスをアプリケーション ロジックから分離するサービスを Store Controller に追加します。
アプリケーションを実行すると、コントローラー サービスが既定でパラメーターとして渡されないため、例外が発生します。
Source\Ex01-Injecting Controller\Begin にある Begin ソリューションを開きます。
作業の続行前に、いくつかの不足している NuGet パッケージをダウンロードする必要があります。 これを行うには、[プロジェクト] メニューをクリックし、[NuGet パッケージの管理] を選択します。
[NuGet パッケージの管理] ダイアログで、[復元] をクリックして、不足しているパッケージをダウンロードします。
最後に、[ビルド] | [ソリューションのビルド] をクリックしてソリューションをビルドします。
Note
NuGet を使用する利点の 1 つは、プロジェクト内のすべてのライブラリを発送する必要がなく、プロジェクト サイズが縮小される点です。 NuGet Power Tools では、Packages.config ファイルでパッケージのバージョンを指定することで、プロジェクトを初回実行するときに必要なすべてのライブラリをダウンロードできます。 このラボから既存のソリューションを開いた後に、これらの手順を実行する必要があるのは、このような理由によります。
Ctrl + F5 キーを押して、デバッグなしでアプリケーションを実行します。 "このオブジェクトにパラメーターなしのコンストラクターは定義されていません" というエラー メッセージが表示されます。
ASP.NET MVC Begin アプリケーションの実行中のエラー
ブラウザーを閉じます。
次の手順では、Music Store ソリューションで、このコントローラーに必要な依存関係を挿入します。
タスク 2 - Unity の MvcMusicStore ソリューションへの追加
このタスクでは、Unity.Mvc3 NuGet パッケージをソリューションに追加します。
Note
Unity.Mvc3 パッケージは、ASP.NET MVC 3 用に設計されていますが、ASP.NET MVC 4 と完全に互換性があります。
Unity は、インスタンスと型のインターセプトをオプションでサポートする、軽量で拡張可能な依存関係の挿入コンテナーです。 これは、任意の種類の .NET アプリケーションで使用できる汎用コンテナーです。 オブジェクトの作成、実行時の依存関係の指定による要件の抽象化、コンテナーへのコンポーネント構成の遅延による柔軟性など、依存関係の挿入メカニズムに含まれるすべての一般的な機能が提供されます。
MvcMusicStore プロジェクトに Unity.Mvc3 NuGet パッケージをインストールします。 これを行うには、[表示] | [その他のウィンドウ] から [パッケージ マネージャー コンソール] を開きます。
次のコマンドを実行します。
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 ブートストラップ初期化子を呼び出してから、依存関係の挿入に使用するサービスとコントローラーを登録するブートストラップ ファイルを更新します。
次に、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 メソッドの内容を、Store Controller と Store Service を登録する次のコードに置き換えます。
(コード スニペット - ASP.NET 依存関係挿入ラボ - Ex01 - Store Controller およびサービスの登録)
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 Music Store
ブラウザーを閉じます。
次の演習では、依存関係の挿入スコープを拡張して、ASP.NET MVC ビューとアクション フィルター内で使用する方法について学習します。
演習 2: ビューの挿入
この演習では、ASP.NET MVC 4 の新機能を使用して Unity を統合し、ビューで依存関係の挿入を使用する方法について学習します。 これを行うには、ストア参照ビュー内でカスタム サービスを呼び出します。このビューには、メッセージと次の画像が表示されます。
次に、プロジェクトを Unity と統合し、カスタム依存関係リゾルバーを作成して依存関係を挿入します。
タスク 1 - サービスを使用するビューの作成
このタスクでは、サービス呼び出しを実行して新しい依存関係を生成するビューを作成します。 このサービスは、このソリューションに含まれる単純なメッセージング サービスです。
Source\Ex02-Injecting View\Begin フォルダーにある Begin ソリューションを開きます。 または、前の演習を完了して取得した End ソリューションを引き続き使用できます。
提供された Begin ソリューションを開いた場合は、続行する前に、不足している NuGet パッケージをダウンロードする必要があります。 これを行うには、[プロジェクト] メニューをクリックし、[NuGet パッケージの管理] を選択します。
[NuGet パッケージの管理] ダイアログで、[復元] をクリックして、不足しているパッケージをダウンロードします。
最後に、[ビルド] | [ソリューションのビルド] をクリックしてソリューションをビルドします。
Note
NuGet を使用する利点の 1 つは、プロジェクト内のすべてのライブラリを発送する必要がなく、プロジェクト サイズが縮小される点です。 NuGet Power Tools では、Packages.config ファイルでパッケージのバージョンを指定することで、プロジェクトを初回実行するときに必要なすべてのライブラリをダウンロードできます。 このラボから既存のソリューションを開いた後に、これらの手順を実行する必要があるのは、このような理由によります。
詳細については、次の記事を参照してください: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages。
Source\Assets フォルダーにある MessageService.cs および IMessageService.cs クラスを /Services に追加します。 これを行うには、Services フォルダーを右クリックして、[既存の項目の追加] を選択します。 ファイルの場所を参照して追加します。
メッセージ サービスとサービス インターフェイスの追加
Note
IMessageService インターフェイスは、MessageService クラスによって実装される 2 つのプロパティを定義しています。 これらのプロパティ (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 を実装して、その依存関係を解決します。 Unity を使用してサービスの取得を処理する IDependencyResolver の実装をソリューションに追加します。 次に、ビューの作成を解決する IViewPageActivator インターフェイスの別のカスタム実装を追加します。
Note
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);
}
プロジェクトのルート フォルダーに /Factories フォルダーを作成します。
CustomViewPageActivator.cs を、/Sources/Assets から Factories フォルダーにあるソリューションに追加します。 これを行うには、/Factories フォルダーを右クリックし、[追加 | 既存の項目] を選択してから、CustomViewPageActivator.cs を選択します。 このクラスは、Unity コンテナーを保持する IViewPageActivator インターフェイスを実装します。
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); } } }
Note
CustomViewPageActivator は、Unity コンテナーを使用してビューの作成を管理します。
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); } } } }
Note
UnityDependencyResolver クラスは、Unity 用のカスタム DependencyResolver です。 Unity コンテナー内でサービスが見つからない場合は、ベース リゾルバーが呼び出されます。
次のタスクでは、両方の実装が登録され、サービスとビューの場所がモデルに通知されます。
タスク 3 - Unity コンテナー内での依存関係の挿入の登録
このタスクでは、これまでの内容をすべて組み合わせて、依存関係の挿入を動作させます。
現時点で、ソリューションには次の要素が含まれています。
- MyBaseClass から継承し、MessageService を使用する参照ビュー。
- サービス インターフェイスに対して依存関係の挿入が宣言されている中間クラス MyBaseClass。
- サービス MessageService とそのインターフェイス IMessageService。
- サービスの取得を処理する 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 - ファクトリ名前空間)
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; }
ASP.NET MVC 4 の既定の依存関係リゾルバーを UnityDependencyResolver のインスタンスに置き換えます。 これを行うには、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); }
Note
ASP.NET MVC は、既定の依存関係リゾルバー クラスを提供しています。 前に Unity 用に作成したのと同様のカスタム依存関係リゾルバーを使用するには、このリゾルバーを置き換える必要があります。
タスク 4 - アプリケーションの実行
このタスクでは、アプリケーションを実行して、Store Browser がサービスを使用し、取得した画像とメッセージを表示することを確認します。
F5 キーを押してアプリケーションを実行します。
[ジャンル] メニュー内の [ロック] をクリックし、MessageService がビューに挿入され、ウェルカム メッセージと画像が読み込まれたことを確認します。 この例では、"ロック" を使用していきます。
MVC Music Store - ビューの挿入
ブラウザーを閉じます。
演習 3: アクション フィルターの挿入
前のハンズオン ラボ「カスタム アクション フィルター」では、フィルターのカスタマイズと挿入に取り組みました。 この演習では、Unity コンテナーを使用して、依存関係の挿入によってフィルターを挿入する方法について学習します。 これを行うには、Music Store ソリューションに、サイトのアクティビティをトレースするカスタム アクション フィルターを追加します。
タスク 1 - ソリューションへの追跡フィルターの追加
このタスクでは、Music Store にイベントをトレースするためのカスタム アクション フィルターを追加します。 カスタム アクション フィルターの概念は、前のラボ「カスタム アクション フィルター」で既に扱っているため、このラボの Assets フォルダーからフィルター クラスを追加して、Unity 用のフィルター プロバイダを作成するだけです。
Source\Ex03 - Injecting Action Filter\Begin フォルダーにある Begin ソリューションを開きます。 または、前の演習を完了して取得した End ソリューションを引き続き使用できます。
提供された Begin ソリューションを開いた場合は、続行する前に、不足している NuGet パッケージをダウンロードする必要があります。 これを行うには、[プロジェクト] メニューをクリックし、[NuGet パッケージの管理] を選択します。
[NuGet パッケージの管理] ダイアログで、[復元] をクリックして、不足しているパッケージをダウンロードします。
最後に、[ビルド] | [ソリューションのビルド] をクリックしてソリューションをビルドします。
Note
NuGet を使用する利点の 1 つは、プロジェクト内のすべてのライブラリを発送する必要がなく、プロジェクト サイズが縮小される点です。 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); } } }
Note
このカスタム アクション フィルターでは、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; } }
Note
フィルター プロバイダ クラス コンストラクターは、内部に新しいオブジェクトを作成していません。 コンテナーはパラメーターとして渡され、依存関係は 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 Platform Installer を使用して、Microsoft Visual Studio Express 2012 for Web または別の "Express" バージョンをインストールできます。 次の手順では、Microsoft Web Platform Installer を使用して 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 Platform Installer がない場合は、最初にダウンロードしてインストールするようにリダイレクトされます。
Web Platform Installer が開いたら、[インストール] をクリックしてセットアップを開始します。
Visual Studio Express をインストールする
すべての製品のライセンスと使用条件を読み、[同意する] をクリックして続行します。
ライセンス条項に同意する
ダウンロードとインストールのプロセスが完了するまで待機します。
インストールの進行状況
インストールが完了したら、[完了] をクリックします。
インストールの完了
[終了] をクリックして Web Platform Installer を閉じます。
Visual Studio Express for Web を開くには、[スタート] 画面に移動し、「VS Express」と記入して、[VS Express for Web] タイルをクリックします。
VS Express for Web タイル
付録 B: コード スニペットの使用
コード スニペットを使用すると、必要なすべてのコードをすぐに入手できます。 ラボ ドキュメントでは、次の図に示すように、使用できるタイミングが正確に示されています。
Visual Studio コード スニペットを使用してプロジェクトにコードを挿入する
キーボードを使用してコード スニペットを追加するには (C# のみ)
- コードを挿入する場所にカーソルを置きます。
- スニペット名の入力を開始します (スペースやハイフンは使用しない)。
- IntelliSense に対応するスニペットの名前が表示されるのを確認します。
- 適切なスニペットを選択します (または、スニペットの名前が完全に選択されるまで入力を続けます)。
- Tab キーを 2 回押して、カーソル位置にスニペットを挿入します。
スニペット名の入力を開始する
Tab キーを押して強調表示されたスニペットを選択する
Tab キーをもう一度押すと、スニペットが展開される
マウスを使用してコード スニペット追加するには (C#、Visual Basic、XML) 1. コード スニペットを挿入する場所を右クリックします。
- [スニペットの挿入] に続いて [マイ コード スニペット] を選択します。
- 関連するスニペットをクリックして、一覧から選択します。
コード スニペットを挿入する場所を右クリックし、[スニペットの挿入] を選択する
関連するスニペットをクリックして、一覧から選択する