ASP.NET MVC 4 – Abhängigkeitsinjektion
Nach Web Camps Team
Download Web Camps Training Kit
In diesem praktischen Labor wird davon ausgegangen, dass Sie grundlegende Kenntnisse über ASP.NET MVC - und ASP.NET MVC 4-Filter haben. Wenn Sie ASP.NET MVC 4-Filter noch nicht verwendet haben, empfehlen wir Ihnen, ASP.NET MVC Custom Action Filters Hands-on Lab zu durchlaufen.
Hinweis
Alle Beispielcode und Codeausschnitte sind im Web Camps Training Kit enthalten, das unter Microsoft-Web/WebCampTrainingKit Releases verfügbar ist. Das für dieses Lab spezifische Projekt ist unter ASP.NET MVC 4 Dependency Injection verfügbar.
Im Paradigma "Objektorientierte Programmierung " arbeiten Objekte in einem Zusammenarbeitsmodell zusammen, in dem Mitwirkende und Verbraucher vorhanden sind. Natürlich generiert dieses Kommunikationsmodell Abhängigkeiten zwischen Objekten und Komponenten und wird schwierig zu verwalten, wenn die Komplexität zunimmt.
Klassenabhängigkeiten und Modellkomplexität
Sie haben wahrscheinlich über das Factorymuster und die Trennung zwischen der Schnittstelle und der Implementierung mit Diensten gehört, wo die Clientobjekte häufig für den Dienststandort verantwortlich sind.
Das Abhängigkeitsinjektionsmuster ist eine bestimmte Implementierung von Inversion von Control. Inversion von Control (IoC) bedeutet, dass Objekte keine anderen Objekte erstellen, auf die sie sich verlassen, um ihre Arbeit zu erledigen. Stattdessen erhalten sie die Objekte, die sie von einer externen Quelle benötigen (z. B. eine XML-Konfigurationsdatei).
Dependency Injection (DI) bedeutet, dass dies ohne den Objekteingriff erfolgt, in der Regel durch eine Frameworkkomponente, die Konstruktorparameter übergibt und Eigenschaften festgelegt.
Designmuster für Abhängigkeitsinjektion (Dependency Injection, DI)
Auf hoher Ebene ist das Ziel von Dependency Injection, dass eine Clientklasse (z. B. der Golfer) etwas benötigt, das eine Schnittstelle (z. B. IClub) erfüllt. Es kümmert sich nicht darum, was der konkrete Typ ist (z. B. WoodClub, IronClub, WedgeClub oder PutterClub), es möchte, dass jemand anderes damit umgeht (z. B. ein guter Caddy). Der Abhängigkeitslöser in ASP.NET MVC kann Es Ihnen ermöglichen, Ihre Abhängigkeitslogik an einer anderen Stelle (z. B. einem Container oder einer Tasche von Clubs) zu registrieren.
Abhängigkeitsinjektion - Golf analogie
Die Vorteile der Verwendung des Abhängigkeitsinjektionsmusters und der Inversion von Control sind die folgenden:
- Reduziert die Klassenkopplung
- Erhöht die erneute Wiederverwendung von Code
- Verbessert die Codeaufrechterhaltung
- Verbessert Anwendungstests
Hinweis
Abhängigkeitsinjektion wird manchmal mit dem Abstrakten Factory Design Pattern verglichen, aber es gibt einen leichten Unterschied zwischen beiden Ansätzen. DI verfügt über ein Framework, das zugrunde arbeitet, um Abhängigkeiten zu lösen, indem die Fabriken und die registrierten Dienste aufgerufen werden.
Nachdem Sie das Dependency Injection Pattern verstanden haben, erfahren Sie in diesem Labor, wie Sie es in ASP.NET MVC 4 anwenden. Sie beginnen mit der Verwendung der Abhängigkeitsinjektion in den Controllern , um einen Datenbankzugriffsdienst einzuschließen. Als Nächstes wenden Sie die Abhängigkeitsinjektion auf die Ansichten an, um einen Dienst zu nutzen und Informationen anzuzeigen. Schließlich erweitern Sie die DI auf ASP.NET MVC 4-Filter, indem Sie einen benutzerdefinierten Aktionsfilter in die Lösung einfügen.
In dieser praktischen Übung erfahren Sie, wie Sie:
- Integrieren ASP.NET MVC 4 mit Unity for Dependency Injection mithilfe von NuGet-Paketen
- Verwenden der Abhängigkeitsinjektion in einem ASP.NET MVC-Controller
- Verwenden der Abhängigkeitsinjektion in einer ASP.NET MVC-Ansicht
- Verwenden der Abhängigkeitsinjektion in einem ASP.NET MVC-Aktionsfilter
Hinweis
This Lab is using Unity.Mvc3 NuGet Package for dependency resolution, but it is possible to adapt any Dependency Injection Framework to work with ASP.NET MVC 4.
Voraussetzungen
Sie müssen über die folgenden Elemente verfügen, um diese Übung abzuschließen:
- Microsoft Visual Studio Express 2012 für Web oder höher (lesen Sie Anhang A , um Anweisungen zur Installation zu erhalten).
Setup
Installieren von Codeausschnitten
Aus Gründen der Einfachheit ist ein Großteil des Codes, den Sie entlang dieser Übung verwalten, als Visual Studio-Codeausschnitte verfügbar. Führen Sie zum Installieren der Codeausschnitte die Datei ".\Source\Setup\CodeSnippets.vsi " aus.
Wenn Sie mit den Visual Studio Code Snippets nicht vertraut sind und erfahren möchten, wie Sie sie verwenden können, finden Sie in diesem Dokument den Anhang "Anhang B: Verwenden von Codeausschnitten".
Übungen
Dieses Hands-On Lab besteht aus den folgenden Übungen:
Hinweis
Jede Übung wird von einem Endordner begleitet, der die resultierende Lösung enthält, die Sie nach Abschluss der Übungen erhalten sollten. Sie können diese Lösung als Leitfaden verwenden, wenn Sie zusätzliche Hilfe beim Durcharbeiten der Übungen benötigen.
Geschätzte Zeit zum Abschließen dieser Übung: 30 Minuten.
Übung 1: Einfügen eines Controllers
In dieser Übung erfahren Sie, wie Sie Dependency Injection in ASP.NET MVC-Controllern verwenden, indem Sie Unity mithilfe eines NuGet-Pakets integrieren. Aus diesem Grund fügen Sie Dienste in Ihre MvcMusicStore-Controller ein, um die Logik vom Datenzugriff zu trennen. Die Dienste erstellen eine neue Abhängigkeit im Controllerkonstruktor, die mithilfe von Dependency Injection mithilfe von Unity aufgelöst wird.
Dieser Ansatz zeigt Ihnen, wie Sie weniger gekoppelte Anwendungen generieren, die flexibler und einfacher zu warten und zu testen sind. Außerdem erfahren Sie, wie Sie ASP.NET MVC in Unity integrieren.
Informationen zum StoreManager-Dienst
Der in der Startlösung bereitgestellte MVC Music Store enthält jetzt einen Dienst, der die Store Controller-Daten mit dem Namen StoreService verwaltet. Unten finden Sie die Store-Dienstimplementierung. Beachten Sie, dass alle Methoden Modellentitäten zurückgeben.
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 aus der Startlösung nutzt jetzt StoreService. Alle Datenverweise wurden von StoreController entfernt, und jetzt kann der aktuelle Datenzugriffsanbieter geändert werden, ohne eine Methode zu ändern, die StoreService nutzt.
Unten finden Sie, dass die StoreController-Implementierung eine Abhängigkeit von StoreService innerhalb des Klassenkonstruktors hat.
Hinweis
Die in dieser Übung eingeführte Abhängigkeit bezieht sich auf Inversion von Steuerelement (IoC).
Der StoreController-Klassenkonstruktor empfängt einen IStoreService-Typparameter , der für die Ausführung von Dienstaufrufen innerhalb der Klasse unerlässlich ist. Der StoreController implementiert jedoch nicht den Standardkonstruktor (ohne Parameter), den ein Controller für ASP.NET MVC verwenden muss.
Um die Abhängigkeit zu beheben, muss der Controller von einer abstrakten Factory erstellt werden (eine Klasse, die ein objekt des angegebenen Typs zurückgibt).
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);
}
}
}
Hinweis
Sie erhalten eine Fehlermeldung, wenn die Klasse versucht, den StoreController zu erstellen, ohne das Dienstobjekt zu senden, da kein parameterloser Konstruktor deklariert ist.
Aufgabe 1 – Ausführen der Anwendung
In dieser Aufgabe führen Sie die Begin-Anwendung aus, die den Dienst in den Store-Controller einschließt, der den Datenzugriff von der Anwendungslogik trennt.
Wenn Sie die Anwendung ausführen, erhalten Sie eine Ausnahme, da der Controllerdienst standardmäßig nicht als Parameter übergeben wird:
Öffnen Sie die Begin-Lösung , die sich in Source\Ex01-Injecting Controller\Begin befindet.
Sie müssen einige fehlende NuGet-Pakete herunterladen, bevor Sie fortfahren. Klicken Sie hierzu auf das Menü "Projekt", und wählen Sie "NuGet-Pakete verwalten" aus.
Klicken Sie im Dialogfeld "NuGet-Pakete verwalten" auf " Wiederherstellen ", um fehlende Pakete herunterzuladen.
Erstellen Sie schließlich die Lösung, indem Sie auf "Buildlösung erstellen | " klicken.
Hinweis
Einer der Vorteile der Verwendung von NuGet besteht darin, dass Sie nicht alle Bibliotheken in Ihrem Projekt versenden müssen, wodurch die Projektgröße reduziert wird. Mit NuGet Power Tools können Sie alle erforderlichen Bibliotheken beim ersten Ausführen des Projekts herunterladen, indem Sie die Paketversionen in der Datei "Packages.config" angeben. Aus diesem Grund müssen Sie diese Schritte ausführen, nachdem Sie eine vorhandene Lösung aus dieser Übung geöffnet haben.
Drücken Sie STRG+F5 , um die Anwendung ohne Debugging auszuführen. Sie erhalten die Fehlermeldung "Kein parameterloser Konstruktor für dieses Objekt definiert":
Fehler beim Ausführen ASP.NET MVC Begin Application
Schließen Sie den Browser.
In den folgenden Schritten arbeiten Sie an der Music Store-Lösung, um die Abhängigkeit dieses Controllers einzuordnen.
Aufgabe 2 – Einschließen von Unity in die MvcMusicStore-Lösung
In dieser Aufgabe fügen Sie Unity.Mvc3 NuGet-Paket in die Lösung ein.
Hinweis
Unity.Mvc3-Paket wurde für ASP.NET MVC 3 entwickelt, ist aber vollständig kompatibel mit ASP.NET MVC 4.
Unity ist ein einfacher, erweiterbarer Container zum Einfügen von Abhängigkeiten mit optionaler Unterstützung für Instanzen und Typabnahmen. Es handelt sich um einen allgemeinen Container für die Verwendung in einem beliebigen .NET-Anwendungstyp. Es stellt alle gängigen Features bereit, die in Abhängigkeitsinjektionsmechanismen enthalten sind, darunter: Objekterstellung, Abstraktion von Anforderungen durch Angeben von Abhängigkeiten zur Laufzeit und Flexibilität, indem die Komponentenkonfiguration auf den Container zurückverzögert wird.
Installieren Sie Unity.Mvc3 NuGet-Paket im MvcMusicStore-Projekt . Öffnen Sie dazu die Paket-Manager Konsole aus "Andere Fenster anzeigen | ".
Führen Sie den folgenden Befehl aus.
PMC
Install-Package Unity.Mvc3
Installieren des Unity.Mvc3 NuGet-Pakets
Nachdem das Unity.Mvc3-Paket installiert wurde, erkunden Sie die Dateien und Ordner, die es automatisch hinzufügt, um die Unity-Konfiguration zu vereinfachen.
Unity.Mvc3-Paket installiert
Aufgabe 3 – Registrieren von Unity in Global.asax.cs Application_Start
In dieser Aufgabe aktualisieren Sie die Application_Start-Methode, die sich in Global.asax.cs befindet, um den Unity Bootstrapper-Initialisierer aufzurufen, und aktualisieren Sie dann die Bootstrapper-Datei, die den Dienst und den Controller registriert, den Sie für Abhängigkeitseinfügung verwenden.
Jetzt verbinden Sie den Bootstrapper, der die Datei ist, die den Unity-Container und den Abhängigkeitslöser initialisiert. Öffnen Sie dazu Global.asax.cs, und fügen Sie den folgenden hervorgehobenen Code in der Application_Start-Methode hinzu.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex01 - Initialize 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(); }
Öffnen Sie Bootstrapper.cs Datei.
Schließen Sie die folgenden Namespaces ein: MvcMusicStore.Services und MusicStore.Controllers.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex01 - Bootstrapper Hinzufügen von Namespaces)
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc3; using MvcMusicStore.Services; using MvcMusicStore.Controllers;
Ersetzen Sie den Inhalt der BuildUnityContainer-Methode durch den folgenden Code, der den Store-Controller und den Store-Dienst registriert.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex01 - Register Store Controller and Service)
private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); container.RegisterType<IStoreService, StoreService>(); container.RegisterType<IController, StoreController>("Store"); return container; }
Aufgabe 4 – Ausführen der Anwendung
In dieser Aufgabe führen Sie die Anwendung aus, um zu überprüfen, ob sie jetzt geladen werden kann, nachdem Unity eingeschlossen wurde.
Drücken Sie F5 , um die Anwendung auszuführen. Die Anwendung sollte jetzt geladen werden, ohne eine Fehlermeldung anzuzeigen.
Ausführen der Anwendung mit Abhängigkeitsinjektion
Navigieren Sie zu /Store. Dadurch wird StoreController aufgerufen, der jetzt mit Unity erstellt wird.
MVC Music Store
Schließen Sie den Browser.
In den folgenden Übungen erfahren Sie, wie Sie den Bereich "Abhängigkeitseinfügung" erweitern, um ihn in ASP.NET MVC-Ansichten und Aktionsfiltern zu verwenden.
Übung 2: Einfügen einer Ansicht
In dieser Übung erfahren Sie, wie Sie Dependency Injection in einer Ansicht mit den neuen Features von ASP.NET MVC 4 für Unity-Integration verwenden. Dazu rufen Sie einen benutzerdefinierten Dienst in der Store-Suchansicht auf, der eine Meldung und ein bild unten anzeigt.
Anschließend integrieren Sie das Projekt in Unity und erstellen einen benutzerdefinierten Abhängigkeitslöser zum Einfügen der Abhängigkeiten.
Aufgabe 1 – Erstellen einer Ansicht, die einen Dienst nutzt
In dieser Aufgabe erstellen Sie eine Ansicht, die einen Dienstaufruf ausführt, um eine neue Abhängigkeit zu generieren. Der Dienst besteht aus einem einfachen Messagingdienst, der in dieser Lösung enthalten ist.
Öffnen Sie die Projektmappe "Begin" , die sich im Ordner "Source\Ex02-Injecting View\Begin " befindet. Andernfalls verwenden Sie möglicherweise die, die Sie durch Ausführen der vorherigen Übung erhalten haben.
Wenn Sie die bereitgestellte Begin-Lösung geöffnet haben, müssen Sie einige fehlende NuGet-Pakete herunterladen, bevor Sie fortfahren. Klicken Sie hierzu auf das Menü "Projekt", und wählen Sie "NuGet-Pakete verwalten" aus.
Klicken Sie im Dialogfeld "NuGet-Pakete verwalten" auf " Wiederherstellen ", um fehlende Pakete herunterzuladen.
Erstellen Sie schließlich die Lösung, indem Sie auf "Buildlösung erstellen | " klicken.
Hinweis
Einer der Vorteile der Verwendung von NuGet besteht darin, dass Sie nicht alle Bibliotheken in Ihrem Projekt versenden müssen, wodurch die Projektgröße reduziert wird. Mit NuGet Power Tools können Sie alle erforderlichen Bibliotheken beim ersten Ausführen des Projekts herunterladen, indem Sie die Paketversionen in der Datei "Packages.config" angeben. Aus diesem Grund müssen Sie diese Schritte ausführen, nachdem Sie eine vorhandene Lösung aus dieser Übung geöffnet haben.
Weitere Informationen finden Sie in diesem Artikel: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.
Schließen Sie die MessageService.cs und die IMessageService.cs Klassen im Ordner "Quelle \Assets " in "/Services" ein. Klicken Sie hierzu mit der rechten Maustaste auf den Ordner "Dienste", und wählen Sie "Vorhandenes Element hinzufügen" aus. Navigieren Sie zum Speicherort der Dateien, und fügen Sie sie ein.
Hinzufügen von Nachrichtendienst und Dienstschnittstelle
Hinweis
Die IMessageService-Schnittstelle definiert zwei Eigenschaften, die von der MessageService-Klasse implementiert werden. Diese Eigenschaften – Message und ImageUrl – speichern die Nachricht und die URL des anzuzeigenden Bilds.
Erstellen Sie den Ordner "/Pages" im Stammordner des Projekts, und fügen Sie dann die vorhandene Klasse MyBasePage.cs aus "Source\Assets" hinzu. Die Basisseite, von der Sie erben, hat die folgende Struktur.
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() { } } }
Öffnen Sie die Ansicht "Browse.cshtml " aus dem Ordner "/Views/Store ", und erben Sie sie von MyBasePage.cs.
@inherits MvcMusicStore.Pages.MyBasePage @{ ViewBag.Title = "Browse Albums"; }
Fügen Sie in der Ansicht "Durchsuchen " einen Aufruf von MessageService hinzu, um ein Bild und eine vom Dienst abgerufene Nachricht anzuzeigen. (C#)
@inherits MvcMusicStore.Pages.MyBasePage @{ Viewbag.Title = "Browse Albums"; } <div> @this.MessageService.Message <br /> <img alt="@this.MessageService.Message" src="@this.MessageService.ImageUrl" /> </div> ...
Aufgabe 2 – Einschließlich eines benutzerdefinierten Abhängigkeitslösers und eines benutzerdefinierten Ansichtsseitenaktivators
In der vorherigen Aufgabe haben Sie eine neue Abhängigkeit in eine Ansicht eingefügt, um einen Dienstaufruf darin auszuführen. Jetzt beheben Sie diese Abhängigkeit, indem Sie die ASP.NET MVC-Abhängigkeitsinjektionsschnittstellen IViewPageActivator und IDependencyResolver implementieren. Sie werden in die Lösung eine Implementierung von IDependencyResolver einschließen, die den Dienstabruf mithilfe von Unity behandelt. Anschließend fügen Sie eine weitere benutzerdefinierte Implementierung der IViewPageActivator-Schnittstelle hinzu, die die Erstellung der Ansichten lösen wird.
Hinweis
Seit ASP.NET MVC 3 hatte die Implementierung für Abhängigkeitsinjektion die Schnittstellen zum Registrieren von Diensten vereinfacht. IDependencyResolver und IViewPageActivator sind Teil ASP.NET MVC 3-Features für Dependency Injection.
- Die IDependencyResolver-Schnittstelle ersetzt die vorherige IMvcServiceLocator. Implementierungen von IDependencyResolver müssen eine Instanz des Diensts oder einer Dienstauflistung zurückgeben.
public interface IDependencyResolver {
object GetService(Type serviceType);
IEnumerable<object> GetServices(Type serviceType);
}
- Die IViewPageActivator-Schnittstelle bietet eine differenziertere Kontrolle darüber, wie Ansichtsseiten über die Abhängigkeitsinjektion instanziiert werden. Die Klassen, die die IViewPageActivator-Schnittstelle implementieren, können Ansichtsinstanzen mithilfe von Kontextinformationen erstellen.
public interface IViewPageActivator {
object Create(ControllerContext controllerContext, Type type);
}
Erstellen Sie den Ordner "/Factories" im Stammordner des Projekts.
Schließen Sie CustomViewPageActivator.cs aus dem Ordner "/Sources/Assets/" in den Ordner "Factories" in Ihre Lösung ein. Klicken Sie dazu mit der rechten Maustaste auf den Ordner "/Fabriken", wählen Sie "Hinzufügen" | aus. Vorhandenes Element und dann CustomViewPageActivator.cs auswählen. Diese Klasse implementiert die IViewPageActivator-Schnittstelle , um den Unity-Container zu enthalten.
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); } } }
Hinweis
CustomViewPageActivator ist für die Verwaltung der Erstellung einer Ansicht mithilfe eines Unity-Containers verantwortlich.
Schließen Sie UnityDependencyResolver.cs Datei aus "/Sources/Assets" in den Ordner "/Factories" ein. Klicken Sie dazu mit der rechten Maustaste auf den Ordner "/Fabriken", wählen Sie "Hinzufügen" | aus. Vorhandenes Element und dann UnityDependencyResolver.cs Datei auswählen.
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); } } } }
Hinweis
UnityDependencyResolver-Klasse ist eine benutzerdefinierte DependencyResolver für Unity. Wenn ein Dienst im Unity-Container nicht gefunden werden kann, wird der Basislöser aufgerufen.
In der folgenden Aufgabe werden beide Implementierungen registriert, um das Modell über den Standort der Dienste und der Ansichten zu informieren.
Aufgabe 3 – Registrieren der Abhängigkeitseinfügung im Unity-Container
In dieser Aufgabe fügen Sie alle vorherigen Dinge zusammen, um Abhängigkeitseinfügungen zu erledigen.
Bis jetzt hat Ihre Lösung die folgenden Elemente:
- Eine Durchsuchenansicht , die von MyBaseClass erbt und MessageService nutzt.
- Eine Zwischenklasse "MyBaseClass", die abhängigkeitsinjektion für die Dienstschnittstelle deklariert hat.
- Ein Dienst - MessageService - und seine Schnittstelle IMessageService.
- Ein benutzerdefinierter Abhängigkeitslöser für Unity – UnityDependencyResolver – das den Dienstabruf behandelt.
- Ein Ansichtsseitenaktivator – CustomViewPageActivator – der die Seite erstellt.
Zum Einfügen der Suchansicht registrieren Sie nun den benutzerdefinierten Abhängigkeitslöser im Unity-Container.
Öffnen Sie Bootstrapper.cs Datei.
Registrieren Sie eine Instanz von MessageService im Unity-Container, um den Dienst zu initialisieren:
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex02 - Register Message Service)
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" }); //... }
Fügen Sie einen Verweis auf den MvcMusicStore.Factories-Namespace hinzu.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex02 - Factories Namespace)
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc3; using MvcMusicStore.Services; using MvcMusicStore.Controllers; using MvcMusicStore.Factories;
Registrieren Sie CustomViewPageActivator als Ansichtsseitenaktivator im Unity-Container:
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex02 - Register 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; }
Ersetzen Sie ASP.NET MVC 4-Standardabhängigkeitslöser durch eine Instanz von UnityDependencyResolver. Ersetzen Sie dazu den Inhalt der Initialize-Methode durch den folgenden Code:
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex02 - Update Dependency Resolver)
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); }
Hinweis
ASP.NET MVC stellt eine Standard-Auflösungsklasse für Abhängigkeiten bereit. Um mit benutzerdefinierten Abhängigkeitslösern zu arbeiten, die wir für Einheit erstellt haben, muss dieser Resolver ersetzt werden.
Aufgabe 4 – Ausführen der Anwendung
In dieser Aufgabe führen Sie die Anwendung aus, um zu überprüfen, ob der Store-Browser den Dienst nutzt, und zeigt das Bild und die abgerufene Nachricht an:
Drücken Sie F5, um die Anwendung auszuführen.
Klicken Sie im Menü "Genres" auf "Rock", und sehen Sie, wie der MessageService in die Ansicht eingefügt und die Willkommensnachricht und das Bild geladen wurde. In diesem Beispiel geben wir "Rock" ein:
MVC Music Store - Einfügung anzeigen
Schließen Sie den Browser.
Übung 3: Einfügen von Aktionsfiltern
In den vorherigen praktischen Übungslabors "Benutzerdefinierte Aktionsfilter" haben Sie mit Filteranpassungen und -einfügungen gearbeitet. In dieser Übung erfahren Sie, wie Sie Mithilfe des Unity-Containers Filter mit Abhängigkeitsinjektion einfügen. Dazu fügen Sie der Music Store-Lösung einen benutzerdefinierten Aktionsfilter hinzu, der die Aktivität der Website nachverfolgt.
Aufgabe 1 – Einschließen des Nachverfolgungsfilters in der Lösung
In dieser Aufgabe fügen Sie im Music Store einen benutzerdefinierten Aktionsfilter ein, um Ereignisse zu verfolgen. Da benutzerdefinierte Aktionsfilterkonzepte bereits in der vorherigen Übung "Benutzerdefinierte Aktionsfilter" behandelt werden, fügen Sie einfach die Filterklasse aus dem Ordner "Assets" dieses Labors ein, und erstellen Sie dann einen Filteranbieter für Unity:
Öffnen Sie die Projektmappe "Begin ", die sich im Ordner "Source\Ex03 - Injecting Action Filter\Begin " befindet. Andernfalls verwenden Sie möglicherweise die, die Sie durch Ausführen der vorherigen Übung erhalten haben.
Wenn Sie die bereitgestellte Begin-Lösung geöffnet haben, müssen Sie einige fehlende NuGet-Pakete herunterladen, bevor Sie fortfahren. Klicken Sie hierzu auf das Menü "Projekt", und wählen Sie "NuGet-Pakete verwalten" aus.
Klicken Sie im Dialogfeld "NuGet-Pakete verwalten" auf " Wiederherstellen ", um fehlende Pakete herunterzuladen.
Erstellen Sie schließlich die Lösung, indem Sie auf "Buildlösung erstellen | " klicken.
Hinweis
Einer der Vorteile der Verwendung von NuGet besteht darin, dass Sie nicht alle Bibliotheken in Ihrem Projekt versenden müssen, wodurch die Projektgröße reduziert wird. Mit NuGet Power Tools können Sie alle erforderlichen Bibliotheken beim ersten Ausführen des Projekts herunterladen, indem Sie die Paketversionen in der Datei "Packages.config" angeben. Aus diesem Grund müssen Sie diese Schritte ausführen, nachdem Sie eine vorhandene Lösung aus dieser Übung geöffnet haben.
Weitere Informationen finden Sie in diesem Artikel: https://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages.
Fügen Sie TraceActionFilter.cs Datei aus "/Sources/Assets" in den Ordner "/Filters" ein.
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); } } }
Hinweis
Dieser benutzerdefinierte Aktionsfilter führt ASP.NET Ablaufverfolgung aus. Weitere Informationen finden Sie unter "ASP.NET lokalen MVC 4- und Dynamische Aktionsfilter".
Fügen Sie die leere Klasse FilterProvider.cs zum Projekt im Ordner "/Filters" hinzu.
Fügen Sie die Namespaces "System.Web.Mvc " und "Microsoft.Practices.Unity " in FilterProvider.cs hinzu.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex03 - Filter provider adding Namespaces)
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 { } }
Stellen Sie fest, dass die Klasse von der IFilterProvider-Schnittstelle erbt.
namespace MvcMusicStore.Filters { public class FilterProvider : IFilterProvider { } }
Fügen Sie eine IUnityContainer-Eigenschaft in der FilterProvider-Klasse hinzu, und erstellen Sie dann einen Klassenkonstruktor, um den Container zuzuweisen.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex03 - Filter Provider Constructor)
public class FilterProvider : IFilterProvider { private IUnityContainer container; public FilterProvider(IUnityContainer container) { this.container = container; } }
Hinweis
Der Klassenkonstruktor des Filteranbieters erstellt kein neues Objekt innerhalb. Der Container wird als Parameter übergeben, und die Abhängigkeit wird von Unity gelöst.
Implementieren Sie in der FilterProvider-Klasse die Methode "GetFilters " von der IFilterProvider-Schnittstelle .
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex03 - Filter Provider 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); } } }
Aufgabe 2 – Registrieren und Aktivieren des Filters
In dieser Aufgabe aktivieren Sie die Websitenachverfolgung. Dazu registrieren Sie den Filter in Bootstrapper.cs BuildUnityContainer-Methode , um die Ablaufverfolgung zu starten:
Öffnen Sie "Web.config" im Projektstamm, und aktivieren Sie die Ablaufverfolgung in der System.Web-Gruppe.
<system.web> <trace enabled="true"/> <compilation debug="true" targetFramework="4.5">
Öffnen Sie Bootstrapper.cs im Projektstamm.
Fügen Sie einen Verweis auf den MvcMusicStore.Filters-Namespace hinzu.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex03 - Bootstrapper Hinzufügen von Namespaces)
using System.Web.Mvc; using Microsoft.Practices.Unity; using Unity.Mvc3; using MvcMusicStore.Services; using MvcMusicStore.Controllers; using MvcMusicStore.Factories; using MvcMusicStore.Filters;
Wählen Sie die BuildUnityContainer-Methode aus, und registrieren Sie den Filter im Unity-Container. Sie müssen den Filteranbieter sowie den Aktionsfilter registrieren.
(Codeausschnitt - ASP.NET Dependency Injection Lab - Ex03 - Register FilterProvider and ActionFilter)
private static IUnityContainer BuildUnityContainer() { var container = new UnityContainer(); //... container.RegisterInstance<IFilterProvider>("FilterProvider", new FilterProvider(container)); container.RegisterInstance<IActionFilter>("LogActionFilter", new TraceActionFilter()); return container; }
Aufgabe 3 – Ausführen der Anwendung
In dieser Aufgabe führen Sie die Anwendung aus und testen, dass der benutzerdefinierte Aktionsfilter die Aktivität nachverfolgt:
Drücken Sie F5, um die Anwendung auszuführen.
Klicken Sie im Menü "Genres" auf "Rock ". Wenn Sie möchten, können Sie zu weiteren Genres navigieren.
Music Store
Navigieren Sie zu "/Trace.axd ", um die Seite "Anwendungsablaufverfolgung" anzuzeigen, und klicken Sie dann auf " Details anzeigen".
Anwendungsablaufverfolgungsprotokoll
Anwendungsablaufverfolgung – Anforderungsdetails
Schließen Sie den Browser.
Zusammenfassung
Indem Sie dieses Hands-On Lab abschließen, haben Sie gelernt, wie Sie Dependency Injection in ASP.NET MVC 4 verwenden, indem Sie Unity mithilfe eines NuGet-Pakets integrieren. Dazu haben Sie Dependency Injection in Controllern, Ansichten und Aktionsfiltern verwendet.
Die folgenden Konzepte wurden behandelt:
- ASP.NET MVC 4 Dependency Injection-Features
- Unity-Integration mit Unity.Mvc3 NuGet-Paket
- Abhängigkeitsinjektion in Controllern
- Abhängigkeitseinfügung in Ansichten
- Abhängigkeitseinfügung von Aktionsfiltern
Anhang A: Installieren von Visual Studio Express 2012 für Web
Sie können Microsoft Visual Studio Express 2012 für Web oder eine andere "Express"-Version mit dem Microsoft-Webplattform Installer installieren. Die folgenden Anweisungen führen Sie durch die Schritte, die zum Installieren von Visual Studio Express 2012 für Web mit Microsoft-Webplattform Installer erforderlich sind.
Wechseln Sie zu /iis/extensions/introduction-to-iis-express/iis-express-overview?linkid=9810169. Wenn Sie das Webplattform-Installationsprogramm bereits installiert haben, können Sie es öffnen und nach dem Produkt "Visual Studio Express 2012 for Web with Windows Azure SDK" suchen.
Klicken Sie auf "Jetzt installieren". Wenn Sie nicht über das Webplattform-Installationsprogramm verfügen, werden Sie umgeleitet, um es zuerst herunterzuladen und zu installieren.
Klicken Sie nach dem Öffnen des Webplattform-Installers auf "Installieren ", um das Setup zu starten.
Installieren von Visual Studio Express
Lesen Sie alle Lizenzen und Bedingungen der Produkte, und klicken Sie auf "Ich stimme zu", um den Vorgang fortzusetzen.
Akzeptieren der Lizenzbedingungen
Warten Sie, bis der Download- und Installationsprozess abgeschlossen ist.
Installationsfortschritt
Wenn die Installation abgeschlossen ist, klicken Sie auf "Fertig stellen".
Installation abgeschlossen
Klicken Sie auf "Beenden ", um den Webplattform-Installer zu schließen.
Um Visual Studio Express für Web zu öffnen, wechseln Sie zum Startbildschirm, und beginnen Sie mit dem Schreiben von "VS Express", und klicken Sie dann auf die VS Express für Webkachel.
VS Express für Webkachel
Anhang B: Verwenden von Codeausschnitten
Mit Codeausschnitten verfügen Sie über den gesamten Code, den Sie benötigen, jederzeit. Das Lab-Dokument teilt Ihnen genau mit, wann Sie sie verwenden können, wie in der folgenden Abbildung dargestellt.
Verwenden von Visual Studio-Codeausschnitten zum Einfügen von Code in Ihr Projekt
So fügen Sie einen Codeausschnitt mithilfe der Tastatur hinzu (nur C#)
- Platzieren Sie den Cursor an der Stelle, an der Sie den Code einfügen möchten.
- Beginnen Sie mit der Eingabe des Codeausschnittnamens (ohne Leerzeichen oder Bindestriche).
- Sehen Sie sich an, wie IntelliSense übereinstimmende Codeausschnittnamen anzeigt.
- Wählen Sie den richtigen Codeausschnitt aus (oder halten Sie die Eingabe, bis der Name des gesamten Codeausschnitts ausgewählt ist).
- Drücken Sie zweimal die TAB-TASTE, um den Codeausschnitt an der Cursorposition einzufügen.
Beginnen Sie mit der Eingabe des Codeausschnittnamens.
Drücken Sie die TAB-TASTE, um den hervorgehobenen Codeausschnitt auszuwählen.
Drücken Sie erneut die TAB-TASTE, und der Codeausschnitt wird erweitert.
So fügen Sie einen Codeausschnitt mit der Maus (C#, Visual Basic und XML) 1 hinzu. Klicken Sie mit der rechten Maustaste auf die Stelle, an der Sie den Codeausschnitt einfügen möchten.
- Wählen Sie "Codeausschnitt einfügen" gefolgt von "Codeausschnitte" aus.
- Wählen Sie den relevanten Codeausschnitt aus der Liste aus, indem Sie darauf klicken.
Klicken Sie mit der rechten Maustaste auf die Stelle, an der Sie den Codeausschnitt einfügen möchten, und wählen Sie "Codeausschnitt einfügen" aus.
Wählen Sie den relevanten Codeausschnitt aus der Liste aus, indem Sie darauf klicken.