Ersetzen Sie den Aktivator für die Middleware in ASP.NET Core

8

Ich versuche, meine ASP.NET Core MVC-Anwendung anzuweisen, einen DI-Container von Drittanbietern zu verwenden. Anstatt einen Adapter zu schreiben, versuche ich, die Bibliothek einfach anzuschließen, indem ich den Rat in diesem Beitrag befolge >

Das funktioniert ziemlich gut - ich kann das eingebaute IControllerActivator durch mein eigenes ersetzen, das den DI-Container verwendet. Ich stoße jedoch in einen Roadblock, wenn ich versuche, benutzerdefinierte Middleware zu instanziieren, die ebenfalls auf injizierten Abhängigkeiten beruht. ASP.NET kann diese Abhängigkeiten nicht auflösen, da es nicht meinen DI-Container von Drittanbietern verwendet - gibt es ein Äquivalent von IControllerActivator für Middleware, oder bin ich mit der integrierten DI oder dem Schreiben eines Adapters nicht weitergekommen?

** EDIT **

Hier ist ein bisschen mehr von meinem Code - ich versuche tatsächlich, Ninject mit dem obigen Muster zu verwenden.

%Vor%

Ich habe festgestellt, dass ich zwei Probleme habe:

  • Ich kann keine Standard-ASP.NET-Komponenten in meine Controller einfügen, weil Ninject sie nicht kennt
  • Meine Middleware, die Anwendungsdienste verwendet, kann nicht instanziiert werden, da ASP.NET Ninject nicht kennt.

Ein Beispiel für das erste Problem ist ein Controller, der nicht instanziiert werden kann, weil ich IUrlHelper verwende (beachte auch ILogger , das auch nicht instanziiert wird):

%Vor%

Hier ist ein Beispiel für das zweite Problem mit einer benutzerdefinierten Middleware:

%Vor%

Mir ist klar, dass ASP.NET-Komponenten in der Theorie in einer eigenen Pipeline sein sollten und meine Anwendungskomponenten in einer anderen sein sollten, aber in der Praxis muss ich häufig Komponenten übergreifend verwenden (wie in den obigen Beispielen).

    
Joshua Barron 07.10.2015, 21:01
quelle

1 Antwort

11

Die SOLID-Prinzipien schreiben vor:

  

Die Abstracts gehören den oberen / Richtlinien-Layern ( DIP )

Das bedeutet, dass unser Anwendungscode nicht direkt vom Framework-Code abhängen sollte, selbst wenn es sich um Abstraktionen handelt. Stattdessen sollten wir Rollenschnittstellen definieren, die auf die Verwendung unserer Anwendung zugeschnitten sind.

Anstatt also von einer Microsoft.Framework.Logging.ILogger -Abstraktion abhängig zu sein, die unseren anwendungsspezifischen Anforderungen entspricht, leiten uns die SOLID-Prinzipien zu Abstraktionen (Ports), die der Anwendung gehören, und verwenden Adapterimplementierungen, die sich in Framework einklinken Code. Hier ist ein Beispiel dafür, wie Ihre eigene ILogger-Abstraktion aussehen könnte.

Wenn Anwendungscode von Ihrer eigenen Abstraktion abhängt, benötigen Sie eine Adapterimplementierung, die den Aufruf an die vom Framework bereitgestellte Implementierung weiterleiten kann:

%Vor%

Dieser Adapter kann wie folgt in Ihrem Anwendungscontainer registriert werden:

%Vor%

BIG WARNING : Macht not direkte Kopien der Framework-Abstraktionen. Das wird fast nie zu guten Ergebnissen führen. Sie sollten Abstraktionen angeben, die in Bezug auf Ihre Anwendung definiert sind. Dies könnte sogar bedeuten, dass ein Adapter komplexer wird und mehrere Framework-Komponenten benötigt, um seinen Vertrag zu erfüllen. Dies führt jedoch zu einem saubereren und wartungsfreundlicheren Anwendungscode.

Aber wenn die Anwendung von SOLID zu mühsam für Sie ist und Sie nur direkt von externen Komponenten abhängig sein möchten, können Sie die erforderlichen Abhängigkeiten in Ihrem Anwendungscontainer immer wie folgt verdrahten:

%Vor%

Es ist so einfach, aber beachten Sie, dass es viel besser ist, anwendungsspezifische Abstraktionen zu definieren, die den SOLID-Prinzipien entsprechen, damit Ihre Anwendung sauber und wartbar bleibt. Beachten Sie auch, dass Sie selbst dann, wenn Sie dies tun, nur einige dieser verkabelten Abhängigkeiten benötigen. Daher sollten Sie Ihren Anwendungscontainer möglichst getrennt vom vNext-Konfigurationssystem aufbewahren.

Bei der Middleware gibt es hier ein ganz anderes Thema. In Ihrer Middleware injizieren Sie Laufzeitdaten (den next -Delegaten) in eine Komponente (die Klasse CustomMiddleware ). Dies führt zu doppeltem Leid, da dies die Registrierung und das Auflösen der Komponente erschwert und verhindert, dass sie vom Container verifiziert und diagnostiziert wird. Stattdessen sollten Sie den next -Delegenten wie folgt aus dem Konstruktor und in den Invoke -Delegaten verschieben:

%Vor%

Jetzt können Sie Ihre Middleware wie folgt in die Pipeline einbinden:

%Vor%

Aber vergessen Sie nicht, dass Sie Ihre Middleware immer wie folgt manuell erstellen können:

%Vor%

Es ist wirklich bedauerlich, dass ASP.NET seine eigenen Dienste ApplicationServices aufruft, weil dort der eigene Anwendungscontainer ist; nicht das eingebaute Konfigurationssystem.

    
Steven 14.10.2015, 07:11
quelle