[ASP.NET
MVC Mavericks Road] 05 – Verwendung von Ninject
Im vorherigen Artikel der [ASP.NET MVC Mavericks Road]-Reihe (Dependency Injection (DI) und Ninject) wurden zwei Dinge erwähnt Tun Sie dies bei der Verwendung von Ninject in ASP.NET
MVC. Im Anschluss an diesen Artikel wird in diesem Artikel anhand eines praktischen Beispiels die Anwendung von Ninject in ASP.NET MVC demonstriert.
Um den Inhalt dieses Artikels besser zu verstehen und zu erfassen, wird Anfängern dringend empfohlen, Dependency Injection (DI) und Ninject zu lesen, bevor sie diesen Artikel lesen.
Verzeichnis dieses Artikels:
Vorbereitungsarbeiten
Erstellen Sie eine neue leere Lösung mit dem Namen BookShop. Fügen Sie der Lösung eine leere MVC-Anwendung namens BookShop.WebUI und ein Klassenbibliotheksprojekt namens BookShop.Domain hinzu. Die Verzeichnisstruktur ist wie folgt:
Nachdem die beiden Projekte hinzugefügt wurden, fügen Sie einen Verweis auf das BookShop.Domain-Projekt unter dem BookShop.WebUI-Projekt hinzu.
Verwenden Sie NuGet, um das Ninject-Paket für das BookShop.WebUI-Projekt bzw. das BookShop.Domain-Projekt zu installieren (für eine Einführung in NuGet lesen Sie bitte Dependency Injection (DI) und Ninject). Sie können die Installation über das visuelle Fenster durchführen oder die Package
Manager-Konsole (Ansicht->Andere Windows->Paket-Manager-Konsole) öffnen und den folgenden Befehl zur Installation ausführen:
Install-Package Ninject -Project BookShop.WebUI
Install-Package Ninject -Project BookShop.Domain
Das folgende Bild zeigt, dass die Installation erfolgreich war:
Controller-Factory erstellen
Wir wissen, dass in ASP.NET MVC eine Client-Anfrage in der Aktion eines bestimmten Controllers verarbeitet wird. Standardmäßig verwendet ASP.NET MVC die integrierte Controller-Factory-Klasse DefaultControllerFactory, um eine Controller-Instanz zu erstellen, die einer bestimmten Anforderung entspricht. Manchmal kann die Standard-Controller-Factory unsere tatsächlichen Anforderungen nicht erfüllen, daher müssen wir dieses Standardverhalten erweitern, das heißt, eine benutzerdefinierte Controller-Factory-Klasse erstellen, die von der DefaultControllerFactory-Klasse erbt und einige ihrer Methoden überschreibt. Zu diesem Zweck erstellen wir einen Ordner mit dem Namen Infrastructure unter dem BookShop.WebUI-Projekt und fügen dem Ordner eine Factory-Klasse mit dem Namen NinjectControllerFactory hinzu. Der Code lautet wie folgt:
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 im obigen Code .Get (controllerType) kann eine Controller-Instanz abrufen. Das manuelle Instanziieren der Controller-Klasse ist hier ein sehr komplizierter Prozess. Wir wissen nicht, ob die Controller-Klasse einen Konstruktor mit Parametern hat, und wir wissen auch nicht, um welche Typen es sich bei den Parametern des Konstruktors handelt. Um Ninject zu verwenden, müssen Sie nur die oben genannte Get-Methode verwenden. Ninject verarbeitet automatisch alle Abhängigkeiten intern und erstellt auf intelligente Weise die von uns benötigten Objekte.
Nachdem die Controller-Factory-Klasse erstellt wurde, müssen wir MVC anweisen, unsere NinjectControllerFactory-Klasse zu verwenden, um ein Controller-Objekt zu erstellen. Fügen Sie dazu den folgenden Code zur Application_Start-Methode der Global.asax-Datei hinzu:
protected void Application_Start() { ...... //设置Controller工厂 ControllerBuilder.Current.SetControllerFactory(new NinjectControllerFactory()); }
Hier ist uns das Prinzip des obigen Codes vorerst egal. Wissen Sie nur, dass Sie sich hier registrieren müssen, wenn ich Zeit habe diesen Teil in einem ausführlicheren Blogbeitrag.
Domänenmodell hinzufügen
In einer MVC-Anwendung dreht sich alles um das Domänenmodell. Deshalb haben wir im BookShop.Domain-Projekt einen Ordner mit dem Namen „Entities“ erstellt, um das Domänen-Entitätsmodell zu speichern. Als E-Commerce-Online-Buchhandlung ist das Buch natürlich die wichtigste Domain-Entität. Da es nur zur Demonstration dient, definieren wir einfach eine Book-Klasse und fügen diese Klasse im Entities-Ordner hinzu. Der Code lautet wie folgt:
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 } ); }
到这,我们的程序可以运行了,效果如下:
Fazit:
Dieser Artikel ist ein einfaches Beispiel für die Verwendung von Ninject in ASP.NET MVC. Der Zweck besteht darin, jedem verständlich zu machen, wie Ninject in MVC verwendet wird. Natürlich ist die Leistungsfähigkeit von Ninject nicht auf das beschränkt, was in diesem Artikel gezeigt wird. Ich glaube, dass Ihnen Niject beim Erstellen von MVC-Anwendungen auf jeden Fall gefallen wird.
Das Obige ist der Inhalt von [ASP.NET MVC Mavericks Road] 05 – Verwendung von Ninject. Weitere verwandte Inhalte finden Sie auf der chinesischen PHP-Website (m.sbmmt.com)!