2015-10-14 12 views
17

Próbuję zrozumieć koncepcję oprogramowania pośredniego w MVC6. Wciąż jest dla mnie niejasna. Naprawdę nie widzę różnic między kilkoma "standardowymi" zmiennymi, które dostajesz w klasie Startup.Różnica między aplikacją, usługami i oprogramowaniem pośrednim w mvc6

Co mogę powiedzieć, że istnieją 3 różne sposoby poinformowania aplikacji, że powinna używać określonego oprogramowania pośredniczącego?

Możesz wywoływać oprogramowanie pośrednie za pomocą usług za pomocą. Ale wydaje się to tylko w przypadku "dodawania" oprogramowania pośredniego?

services.AddMvc(); 

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

Następnie masz IApplicationBuilder app. Czy rzeczywiście używasz oprogramowania pośredniego załadowanego do usług? Tak można nazwać to lubią:

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

I wtedy istnieje sposób, aby załadować i wykorzystanie middleware tak:

app.UseMiddleware<MyCustomMiddleware>(); 

Jaka jest korzyść posiadające trzy rodzaje rejestracji/użyciu oprogramowanie pośrednie? Jakie są dokładne różnice między nimi?

Odpowiedz

12

chciałbym rozróżnić dodając usługi i dodanie warstwy pośredniej.

Dodawanie usługi

To jest w zasadzie rejestracji klas potrzebnych swojej funkcji do zbiornika wtrysku zależność zbudowany w ASP .NET 5. (interfejs IServiceCollection)

Najprostszą rzeczą można zrobić to ręcznie dodać je jeden po drugim, jak w:

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

Jeśli budujesz bardziej złożoną aplikację lub autonomiczne ramy, może chcesz utworzyć funkcja rejestrująca wszystkie potrzebne usługi.Dobrym sposobem na osiągnięcie tego jest tworzenie metodę rozszerzenia:

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(); 

To jest dokładnie to, co services.AddMvc(); robi.

W sposób bardziej elastyczny, ponieważ pozwala przekazać lambda do dalszego dostosowywania usług domyślnych jak model spoiwa (np services.AddMvc(opts => opts.ModelBinders ...)) i jest zwrócenie IMvcBuilder można wykorzystać do dalszego dostosować go rzeczy jak silniki widzenia (Podobnie jak services.AddMvc().AddViewOptions(opts => opts.ViewEngines ...)).

Dodawanie middleware

ASP .Net 5 nie jest oparty na modułach HTTP oraz podnośników, a zamiast tego opiera się na idei OWIN oprogramowania pośredniczącego. Jest [ładny wpis w blogu] (http://dzimchuk.net/post/understanding-aspnet-5-middleware) przez Andrei Dzimchuk opisując middleware który ładnie podsumowuje:

Middleware - Pass through składników, które tworzą rurociąg pomiędzy serwerem a aplikacją do wglądu, route lub modyfikuj komunikaty o żądaniach i odpowiedziach w określonym celu.

Ta definicja dotyczy również programu ASP.NET 5. Middleware można uważać za oba moduły HTTP i programy obsługi, które mieliśmy w klasycznym ASP.NET. Niektóre oprogramowanie pośredniczące implementowałoby różne pośrednie zadania podczas przetwarzania żądań, takich jak uwierzytelnianie, pobieranie stanu sesji i utrwalanie, rejestrowanie i tak dalej. Niektóre z nich byłyby ostatecznymi procedurami obsługi zapytań, które dawałyby odpowiedzi.

Teraz chcesz dodać własne zachowanie do potoku ASP.

Najprostszą rzeczą jest zdefiniowanie middleware inline:

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

Można również create your own middleware class i zarejestrować go:

app.UseMiddleware<MyMiddleware>(); 

Wreszcie, można ponownie zdefiniować metody rozszerzenie do hermetyzacji złożoną logikę konfiguracji.

To właśnie robi app.UseMvc(). Umożliwia zdefiniowanie tras, a następnie dodanie oprogramowania pośredniczącego do routingu, dzwoniąc pod numer app.UseRouter(). Jak widać, wdrożenie app.UseRouter dodaje RouterMiddleware do rurociągu z wezwaniem do builder.UseMiddleware<RouterMiddleware>(router);

wszelkie usługi potrzebne przez middleware byłby wcześniej zarejestrowane. Oznacza to, że będą dostępne dla oprogramowania pośredniego poprzez wbudowany kontener DI.


Końcowym rezultatem jest to, że struktura sprawia, że ​​łatwiej jest w zasadzie łączyć składniki (usług) i zachowanie (middleware) potrzebnych aplikacji, w tym tylko bity, które trzeba.

+0

link był bardzo pomocny, dzięki – wodzu

2

Istnieją dwa etapy budowy rurociągu:

  • usługi rejestrując DI
  • Dodanie middleware do rurociągu

AddMvc rejestruje usługi MVC potrzebuje (np widok silnik, formatator JSON itp.), ale nie dodaje niczego do potoku.

UseMiddleware<T> to ogólna metoda dodawania oprogramowania pośredniego do potoku. Ta metoda użyje systemu DI do wykonywania wstrzyknięć za pośrednictwem konstruktora klasy middleware.

UseMvc i tym podobne są metody rozszerzenia, które ułatwiają przekazywanie opcji konfiguracyjnych. Jeśli piszesz niestandardowe oprogramowanie pośredniczące, możesz po prostu zadzwonić pod numer UseMiddleware<T> lub podać metodę rozszerzenia, w zależności od tego, jak skonfigurować oprogramowanie pośredniczące.

można znaleźć więcej informacji tutaj: https://docs.asp.net/en/latest/fundamentals/middleware.html

7

Chciałbym dodać do Daniela odpowiedź na praktyczny przykład. (jego odpowiedź jest bardzo szczegółowa i poprawna, najpierw sprawdź to).

TL; DR:

services.Add nie jest bezpośrednio związane z middleware. Chodzi o rejestrowanie zależności w Dependency Injection Container.

app.Use polega na wybieraniu czereśni, który kod będzie działał w potoku (do logiki), w jakiej kolejności, i jeśli pozwala na kontynuowanie przetwarzania potoku. Wyobraźnia jest granicą tutaj, jednym z przykładów byłoby pisanie middleware, że w zależności od adresu IP, można pokazać stronę, która mówi: „Niestety usługa nie jest dostępna w Twoim kraju”)

app.UseMiddleware jest taka sama jak app.Use ale zamiast deklarować kod w linii, określasz klasę, która będzie miała metodę Invoke, która będzie dla ciebie wywoływana.

Teraz przejdźmy do jakiegoś przykładowego kodu:

Powiedzmy chcesz aplikację przetworzyć wyjście lub niektórych wydrukach, jak minifing kod HTML.

Możesz dodać oprogramowanie pośrednie, które przechwytuje odpowiedź, zanim zostanie zapisane na wyjściu i zminimalizować je.

Więc można użyć:

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); 

}); 

Jeśli chcesz podzielić się swoją middleware w różnych aplikacjach lub przez innych, może chcesz stworzyć middleware i użyć go bardziej jak:

app.UseMiddleware<HtmlMinifierMiddleware>(); 

wykona całą pracę za pomocą pojedynczego wiersza kodu w metodzie configure. Powszechną praktyką jest wysyłanie metod rozszerzeń, takich jak app.UseHtmlMinifier() i zwracanie określonych obiektów, które mogą być powiązane dla konfiguracji lub parametrów konfiguracyjnych wsparcia. Używanie rozszerzenia daje dużo elastyczności, czytelność i API ujawniania: D

teraz wyobrazić swoją middleware jest delcared coś takiego:

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

jak widać, trzeba zdać IHtmlMinifer, więc trzeba zarejestrować go dla DI.

ta realizowana jest na ConfigureService jak:

services.AddScoped<IHtmlMinifier, MyCoolHtmlMinifier>(); 

teraz wyobraź sobie, że nie potrzebujemy 1, ale wiele zależności, to będzie się do autora/konsumenta middleware znać każdy pojedynczy zależność, która musi być zarejestrowany.

Autorzy oprogramowania pośredniego zwykle wysyłają rozszerzenie, aby ułatwić korzystanie z programistów takich jak: services.AddHtmlMinifier(), co jest właśnie tym sposobem rozszerzenia usług rejestru do DI Container.

Nawet jeśli nie korzystasz z oprogramowania pośredniego, możesz wykorzystać zależność własnej aplikacji przy użyciu tego samego wzorca.

Na przykład, jeśli aplikacja jest e-commerce, można utworzyć metody rozszerzenie, które rejestrują swoje zależności: services.AddProductManagement(), services.AddPriceCalculator(), services.AddSearching(), itp, lub po prostu services.AddMyCoolApplication() aby zapewnić czysty sposób dodawania (rejestracji) swoich usług (zależności) do znalezienia przez DI Container dla twojej aplikacji.

+1

bardzo pomocne, dzięki. – wodzu

Powiązane problemy