[ASP.NET
MVC Mavericks Road] 05 - Ninject の使用
[ASP.NET MVC Mavericks Road] シリーズの前回の記事 (Dependency Injection (DI) と Ninject) の最後で、ASP では次のことが述べられました。 NET
MVC で Ninject を使用する場合、行うべきことは 2 つあります。この記事では、ASP.NET MVC での Ninject のアプリケーションを実際の例を使用して説明します。
この記事の内容をよりよく理解して把握するために、初心者はこの記事を読む前に依存性注入 (DI) と Ninject を読むことを強くお勧めします。
この記事のディレクトリ:
準備
BookShop という新しい空のソリューションを作成します。 BookShop.WebUI という名前の空の MVC アプリケーションと BookShop.Domain という名前のクラス ライブラリ プロジェクトをソリューションに追加します。ディレクトリ構造は次のとおりです。
2 つのプロジェクトを追加した後、BookShop.WebUI プロジェクトの下に BookShop.Domain プロジェクトへの参照を追加します。
NuGet を使用して、BookShop.WebUI プロジェクトと BookShop.Domain プロジェクトの Ninject パッケージをそれぞれインストールします (NuGet の概要については、「依存性注入 (DI) と Ninject」をお読みください)。ビジュアル ウィンドウからインストールすることも、パッケージ
マネージャー コンソール ([表示] -> [その他のウィンドウ] -> [パッケージ マネージャー コンソール]) を開いて次のコマンドを実行してインストールすることもできます:
Install-Package Ninject -Project BookShop.WebUI
Install-Package Ninject - Project BookShop.Domain
次の図は、インストールが成功したことを示しています:
Create Controller Factory
ASP.NET MVC では、クライアント要求が action のアクションで処理されることがわかっています。特定のコントローラー。 デフォルトでは、ASP.NET MVC は組み込みのコントローラー ファクトリ クラス DefaultControllerFactory を使用して、特定の要求に対応するコントローラー インスタンスを作成します。場合によっては、デフォルトのコントローラー ファクトリが実際のニーズを満たせない場合があるため、このデフォルトの動作を拡張する必要があります。つまり、DefaultControllerFactory クラスを継承するカスタム コントローラー ファクトリ クラスを作成し、そのメソッドの一部をオーバーライドする必要があります。このために、BookShop.WebUI プロジェクトの下に Infrastructure という名前のフォルダーを作成し、そのフォルダーに NinjectControllerFactory という名前のファクトリ クラスを追加します。コードは次のとおりです。上記のコードの
public class NinjectControllerFactory : DefaultControllerFactory { private IKernel ninjectKernel; public NinjectControllerFactory() { ninjectKernel = new StandardKernel(); AddBindings(); } protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType) { return controllerType == null ? null : (IController)ninjectKernel.Get(controllerType); } private void AddBindings() { // todo:后面再来添加绑定 } }
ninjectKernel.Get(controllerType) は、コントローラーインスタンス。ここでコントローラー クラスを手動でインスタンス化するのは、非常に複雑なプロセスです。コントローラー クラスにパラメーターを持つコンストラクターがあるかどうかも、コンストラクターのパラメーターの型もわかりません。 Ninject を使用するには、上記の Get メソッドを使用するだけで済みます。Ninject はすべての依存関係を内部で自動的に処理し、必要なオブジェクトをインテリジェントに作成します。
コントローラー ファクトリ クラスが作成されたら、NinjectControllerFactory クラスを使用してコントローラー オブジェクトを作成するように MVC に指示する必要があります。これを行うには、Global.asax ファイルの Application_Start メソッドに次のコードを追加します。今のところは気にしません。上記のコードの原理は何ですか? カスタム コントローラー ファクトリを設定するには、ここに登録するだけで済みます。時間があれば、この部分についてさらに詳しく説明します。
public class Book { public int ID { get; set; } public string Title { get; set; } public string Isbn { get; set; } public string Summary { get; set; } public string Author { get; set; } public byte[] Thumbnail { get; set; } public decimal Price { get; set; } public DateTime Published { get; set; } }
添加Repository
我们知道,我们肯定需要一种方式来从数据库中读取Book数据。在这我们不防为数据的使用者(这里指Controller)提供一个IBookRepository接口,在这个接口中声明一个IQueryable
public interface IBookRepository { IQueryable<Book> Books { get; } }
在MVC中我们一般会用仓储模式(Repository Pattern)把数据相关的逻辑和领域实体模型分离,这样对于使用者来说,通过调用仓储对象,使用者可以直接拿到自己想要的数据,而完全不必关心数据具体是如何来的。我们可以把仓储比喻成一个超市,超市已经为消费者供备好了商品,消费者只管去超市选购自己需要的商品,而完全不必关心这些商品是从哪些供应商怎么样运输到超市的。但对于仓储本身,必须要实现读取数据的“渠道”。
在BookShop.Domain工程中添加一个名为Concrete文件夹用于存放具体的类。我们在Concrete文件夹中添加一个实现了IBookRepository接口的BookRepository类来作为我们的Book数据仓储。BookRepository类代码如下:
public class BookRepository : IBookRepository { public IQueryable<Book> Books { get { return GetBooks().AsQueryable(); } } private static List<Book> GetBooks() { //为了演示,这里手工造一些数据,后面会介绍使用EF从数据库中读取。 List<Book> books = new List<Book>{ new Book { ID = 1, Title = "ASP.NET MVC 4 编程", Price = 52}, new Book { ID = 2, Title = "CLR Via C#", Price = 46}, new Book { ID = 3, Title = "平凡的世界", Price = 37} }; return books; } }
为了演示,上面是手工造的一些数据,后面的文章我将介绍使用Entity Framwork从数据库中读取数据。对于刚接触ORM框架的朋友可能对这里IQueryable感到奇怪,为什么用IQueryable作为返回类型,而不用IEnumerable呢?后面有机会讲Entity Framwork的时候再讲。
添加绑定
打开之前我们在BookShop.WebUI工程创建的NinjectControllerFactory类,在AddBindings方法中添加如下代码
private void AddBindings() { ninjectKernel.Bind<IBookRepository>().To<BookRepository>(); }
这句代码,通过Ninject把IBookRepository接口绑定到BookRepository,当IBookRepository接口的实现被请求时,Ninject将自动创建BookRepository类的实例。
到这里,Ninject的使用步骤就结束了,接下来我们把本示例剩余的步骤完成。
显示列表
右击BookShop.WebUI工程的Controllers文件夹,添加一个名为Book的Controller,按下面代码对其进行编辑:
public class BookController : Controller { private IBookRepository repository; public BookController(IBookRepository bookRepository) { repository = bookRepository; } }
在这,BookController的构造函数接受了一个IBookRepository参数,当BookController被实例化的时候,Ninject就为其注入了BookRepository的依赖。接下来我们为这个Controller添加一个名为List的Action,用来呈现Book列表。代码如下:
public class BookController : Controller { ... public ViewResult List() { return View(repository.Books); } }
当然我们需要添加一个View。右击上面的List方法,选择添加视图,在弹出的窗口进行如下配置:
然后我们在List.cshtml中用foreach循环来列举书本信息,代码如下:
@model IEnumerable<BookShop.Domain.Entities.Book> @{ ViewBag.Title = "Books"; } @foreach (var p in Model) { <div class="item" style="border-bottom:1px dashed silver;"> <h3>@p.Title</h3> <p>价格:@p.Price.ToString("c") </p> </div> }
最后我们还需要修改一下默认路由,让系统运行后直接导向到我们的{controller = "Book", action = "List"},打开Global.asax文件,找到RegisterRoutes方法,进行如下修改:
public static void RegisterRoutes(RouteCollection routes) { routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute( "Default", // Route name "{controller}/{action}/{id}", // URL with parameters new { controller = "Book", action = "List", id = UrlParameter.Optional } ); }
到这,我们的程序可以运行了,效果如下:
結論:
この記事は、ASP.NET MVC での Ninject の使用方法を誰もが理解できるようにすることを目的としています。もちろん、Ninject の能力はこの記事で説明したものに限定されるものではありません。Niject に慣れると、MVC アプリケーションを構築するときに必ず気に入っていただけると思います。
上記は、[ASP.NET MVC Mavericks Road] 05 - Ninject の使用の内容です。その他の関連コンテンツについては、PHP 中国語 Web サイト (www.php.cn) に注目してください。