2015-10-14 3 views
17

Ich versuche, das Konzept der Middleware in MVC6 zu verstehen. Es ist immer noch irgendwie vage für mich. Ich sehe nicht wirklich die Unterschiede zwischen ein paar "Standard" Variablen, die Sie in der Startup Klasse bekommen.Unterschied zwischen App, Dienste und Middleware in mvc6

Soweit ich sagen kann gibt es 3 verschiedene Möglichkeiten, der Anwendung zu sagen, dass es eine bestimmte Middleware verwenden sollte?

Sie können Middleware über Dienste mit aufrufen. Aber das scheint nur für das Hinzufügen von Middleware?

services.AddMvc(); 

// Add other services 
services.AddScoped<IMyCountriesRepository, MyCountriesRepository>(); 
services.AddScoped<IEmailer, Emailer>(); 

Dann haben Sie IApplicationBuilder app. Dies ist eigentlich die Middleware, die in den Diensten geladen ist? So können Sie es gerne nennen:

app.UseMvc(); 
app.UseErrorPage(...); 
app.UseIdentity(); // cookie authentication 

Und dann gibt es eine Möglichkeit, und die Verwendung Middleware wie folgt zu laden:

app.UseMiddleware<MyCustomMiddleware>(); 

Was ist der Nutzen drei Arten von aufweist, ist die Registrierung/ mit Middleware? Was sind die genauen Unterschiede zwischen ihnen?

Antwort

12

ich zwischen dem Hinzufügen der Dienste und das Hinzufügen der Middleware unterscheiden würde.

die Dienste Hinzufügen

Dies ist im Grunde die Klassen durch Ihre Funktion in der Dependency Injection Container in ASP .Net 5. (Die IServiceCollection Schnittstelle)

Die einfachste Sache gebaut benötigt Registrierung möglich tun wird, um sie nacheinander manuell hinzufügen, wie in:

services.AddScoped<IMyCountriesRepository, MyCountriesRepository>(); 
services.AddScoped<IEmailer, Emailer>(); 

Wenn Sie eine komplexere App bauen, oder ein in sich geschlossenes Framework, möchten Sie vielleicht ein erstellen Funktion, die alle benötigten Dienste registriert.Eine gute Möglichkeit, dies zu tun ist durch eine Erweiterungsmethode zu schaffen:

public static void AddMyServices(this IServiceCollection services) 
{ 
    services.AddScoped<IMyCountriesRepository, MyCountriesRepository>(); 
    services.AddScoped<IEmailer, Emailer>(); 
    ... 
} 

//register all your services just by running the ext method: 
services.AddMyServices(); 

das ist genau das, was services.AddMvc(); tut.

In einer flexibleren Art und Weise, wie es Ihnen einen Lambda passieren zu weiteren Standarddienste wie das Modells Bindemittel (wie services.AddMvc(opts => opts.ModelBinders ...)) anpassen und kehrt ein IMvcBuilder Sie weiter verwenden können, um es Dinge wie die Ansicht Motoren anpassen (Wie services.AddMvc().AddViewOptions(opts => opts.ViewEngines ...)).

Hinzufügen von Middleware

ASP .Net 5 ist in HTTP-Module und Handler basiert, und stattdessen basiert auf der Idee OWIN von Middleware. Es gibt einen [schönen Blog-Eintrag] (http://dzimchuk.net/post/understanding-aspnet-5-middleware) von Andrei Dzimchuk die Middleware zu beschreiben, die schön fasst es:

Middleware - Fahren Sie durch Komponenten, die eine Pipeline zwischen einem Server und Anwendung bilden zu inspizieren, route oder ändern Sie Anforderungs- und Antwortnachrichten für einen bestimmten Zweck.

Und diese Definition gilt auch für ASP.NET 5. Middleware kann sowohl als HTTP-Module als auch als Handler betrachtet werden, die wir in klassischem ASP.NET hatten. Einige Middleware würde verschiedene Zwischenaufgaben bei der Verarbeitung von Anforderungen wie Authentifizierung, Abruf von Sitzungsstatus und Persistenz, Protokollierung usw. implementieren. Einige von ihnen wären die ultimativen Request-Handler, die Antworten liefern würden.

So jetzt möchten Sie Ihr eigenes Verhalten in die ASP-Pipeline hinzufügen.

Die einfachste Sache ist, eine Inline-Middleware definieren:

app.Use(async (context, next) => 
{ 
    //do something before passing the request to the next middleware 
    await next.Invoke(); 
}); 

können Sie auch create your own middleware class und registrieren sie:

app.UseMiddleware<MyMiddleware>(); 

Schließlich könnten Sie wieder Erweiterungsmethoden definieren komplexe Setup-Logik zu kapseln.

Dies ist, was app.UseMvc() tut. Sie können Ihre Routen definieren und dann die Routing-Middleware hinzufügen, indem Sie app.UseRouter() aufrufen. Wie Sie sehen können, fügt die Implementierung von app.UseRouter die RouterMiddleware in die Pipeline mit dem Aufruf von builder.UseMiddleware<RouterMiddleware>(router);

Irgendwelche von Middleware benötigten Dienste vorher registriert worden wäre. Dies bedeutet, dass sie für Ihre Middleware über den integrierten DI-Container verfügbar sind.


Das Endergebnis ist, dass der Rahmen leichter macht für Sie grundsätzlich zu mischen und die Komponenten (Dienste) und Verhalten (Middleware) entsprechen die von Ihrer Anwendung benötigt werden, die nur die Bits, die Sie benötigen.

+0

der Link war sehr hilfreich, danke – wodzu

2

Es gibt zwei Phasen, die Pipeline zu bauen:

  • Dienste für DI Registrierung
  • die Middleware an die Pipeline

AddMvc Hinzufügen registriert die Dienste, die MVC muss (zB die Ansicht Engine, der JSON-Formatierer usw.), fügt jedoch nichts zur Pipeline hinzu.

UseMiddleware<T> ist eine generische Methode zum Hinzufügen von Middleware zur Pipeline. Diese Methode verwendet das DI-System, um Abhängigkeiten über den Konstruktor der Middleware-Klasse zu injizieren.

UseMvc und ähnliche sind Erweiterungsmethoden, die das Übergeben von Konfigurationsoptionen erleichtern. Wenn Sie benutzerdefinierte Middleware schreiben, können Sie einfach UseMiddleware<T> aufrufen oder eine Erweiterungsmethode angeben, je nachdem, wie Sie die Middleware einrichten müssen.

können Sie weitere Informationen finden Sie hier: https://docs.asp.net/en/latest/fundamentals/middleware.html

7

Ich mag es, Daniel ein praktisches Beispiel zu beantworten. (seine Antwort ist sehr detailliert und korrekt, überprüfe das zuerst).

TL; DR:

services.Add ist nicht direkt mit Middleware zusammen. Es geht darum, Abhängigkeiten im Dependency-Injection-Container zu registrieren.

app.Use ist über Rosinenpicken, welcher Code in der Pipeline laufen wird (Logik machen), in welcher Reihenfolge, und ob die Pipeline weiter verarbeitet werden darf oder nicht. Die Phantasie ist die Grenze hier wäre ein Beispiel eine Middleware werden writting, die in Abhängigkeit von der IP-Adresse, Sie eine Seite zeigen, die sagen: "Entschuldigung Service in Ihrem Land nicht verfügbar ist)

app.UseMiddleware es ist das gleiche wie app.Use Anstatt jedoch den Code inline zu deklarieren, geben Sie eine Klasse an, die über eine Invoke-Methode verfügt, die für Sie aufgerufen wird. Jetzt

, lassen Sie uns bis zu einem gewissen Beispielcode erhalten:

Angenommen, Sie haben Ihre Anwendung die Ausgabe oder einige Ihrer Ausgabe zu verarbeiten, wie Sie Ihre HTML minifing.

Sie können eine Middleware hinzufügen, die die Antwort abfängt, bevor sie in die Ausgabe geschrieben und minimiert wird.

So können Sie verwenden:

app.Use(async (context, next) => 
{ 
    await next(context); 
    context.Response // will have the response as processed by all the previous middleswares like mvc. 
    if IsMinifiable(context.Response) 
    MinifyResponse(context.Response); 

}); 

Wenn Sie Ihre Middleware in verschiedenen Anwendungen teilen oder von anderen, können Sie eine Middleware erstellen möchten, und verwenden Sie es eher wie:

app.UseMiddleware<HtmlMinifierMiddleware>(); 

Das erledigt die ganze Arbeit für Sie mit einer einzigen Codezeile in der configure-Methode. Es ist üblich, Erweiterungsmethoden wie app.UseHtmlMinifier() zu versenden und bestimmte Objekte zurückzugeben, die zur Konfiguration oder zur Unterstützung von Konfigurationsparametern verkettet werden können. Mit Erweiterungen viel Flexibilität bietet, Lesbarkeit und api Auffindbarkeit: D

jetzt vorstellen, Middleware so etwas wie dieses delcared ist:

public class HtmlMinifierMiddleware { 
    public HtmlMinifier(IHtmlMinifier minifier) { 
     // ... 
    } 
    public string Minify(string content) { 
     return minifier.Minify(content); 
    } 
    // ... 
} 

wie Sie sehen können, können Sie einen IHtmlMinifer geben müssen, so müssen Sie um es für die DI zu registrieren.

services.AddScoped<IHtmlMinifier, MyCoolHtmlMinifier>(); 

jetzt vorstellen, Sie brauchen nicht mehr als 1, aber viele Abhängigkeiten hat, wird es an den Entwickler/Verbraucher der Middleware jede einzelne Abhängigkeit zu wissen, dass sein muss:

dies auf ConfigureService wie erreicht Eingetragen.

Autoren von Middleware liefert normalerweise eine Erweiterung, um die Verwendung von Entwicklern wie: services.AddHtmlMinifier() zu erleichtern, was genau das ist, eine Erweiterungsmethode für Registerdienste in den DI-Container.

Auch wenn Sie keine Middleware verwenden, können Sie die Abhängigkeit Ihrer eigenen Anwendung mit demselben Muster nutzen.

Zum Beispiel, wenn Ihre Anwendung ein E-Commerce ist, können Sie Erweiterungsmethoden erstellen, die Ihre Abhängigkeiten registrieren: services.AddProductManagement(), services.AddPriceCalculator(), services.AddSearching(), etc, OR services.AddMyCoolApplication() nur eine saubere Art und Weise der Zugabe zu bieten (Registrierung) Ihre Dienste (Abhängigkeiten) vom DI Container für Ihre Anwendung gefunden werden.

+1

sehr hilfreich, danke. – wodzu

Verwandte Themen