Beiträge
Wann das FromService-Attribut verwendet werden sollte
20. November 2019 • 3 Min. Lesezeit

Ich habe kürzlich das [FromServices]
-Attribut entdeckt, das seit der ersten Version Teil von .Net Core ist.
Das [FromServices]-Attribut ermöglicht Dependency Injection auf Methodenebene in Asp.Net Core Controllern.
Hier ist ein Beispiel:
public class UserController : Controller
{
private readonly IApplicationSettings _applicationSettings;
public UserController(IApplicationSettings applicationSettings)
{
_applicationSettings = applicationSettings;
}
public IActionResult Get([FromService]IUserRepository userRepository, int userId)
{
//Do magic
}
}
Warum sollte man Method Injection anstelle von Constructor Injection verwenden? Die gängige Erklärung ist, wenn eine Methode Abhängigkeiten benötigt und diese nirgendwo anders verwendet werden, dann ist sie ein Kandidat für die Verwendung des [FromService]
-Attributs.
Steven von StackOverflow hat eine Antwort gegen die Verwendung des [FromService]
-Attributs gepostet:
Für mich ist die Verwendung dieser Art von Method Injection in Controller-Aktionen eine schlechte Idee, weil:
– Ein solches
[FromServices]
-Attribut kann leicht vergessen werden, und Sie werden es nur herausfinden, wenn die Aktion aufgerufen wird (anstatt es beim Anwendungsstart herauszufinden, wo Sie die Konfiguration der Anwendung überprüfen können)– Die Notwendigkeit, aus Leistungsgründen von Constructor Injection wegzugehen, ist ein klares Zeichen dafür, dass injizierte Komponenten zu schwer zu erstellen sind, während Injection-Konstruktoren einfach sein sollten, und die Komponentenerstellung sollte daher sehr leichtgewichtig sein.
– Die Notwendigkeit, von Constructor Injection wegzugehen, um zu verhindern, dass Konstruktoren zu groß werden, ist ein Hinweis darauf, dass Ihre Klassen zu viele Abhängigkeiten haben und zu komplex werden. Mit anderen Worten, viele Abhängigkeiten zu haben ist ein Hinweis darauf, dass die Klasse das Single Responsibility Principle verletzt. Die Tatsache, dass Ihre Controller-Aktionen leicht auf verschiedene Klassen aufgeteilt werden können, ist ein Beweis dafür, dass ein solcher Controller nicht sehr kohäsiv ist und daher ein Hinweis auf eine SRP-Verletzung.
Anstatt also das Grundproblem mit der Verwendung von Method Injection zu verbergen, empfehle ich die Verwendung von Constructor Injection als einziges Injection-Muster hier und machen Sie Ihre Controller kleiner. Das könnte jedoch bedeuten, dass Ihr Routing-Schema sich von Ihrer Klassenstruktur unterscheidet, aber das ist völlig in Ordnung und wird von ASP.NET Core vollständig unterstützt.
Aus Sicht der Testbarkeit sollte es übrigens nicht wirklich wichtig sein, wenn es manchmal eine Abhängigkeit gibt, die nicht benötigt wird. Es gibt effektive Testmuster, die dieses Problem lösen.
Ich stimme Steven zu; wenn Sie Ihre Abhängigkeiten von Ihrem Controller zur Methode verschieben müssen, weil die Klasse zu viele Abhängigkeiten konstruiert, dann ist es Zeit, den Controller aufzuteilen. Sie verletzen höchstwahrscheinlich das SRP.
Der einzige Anwendungsfall, den ich für Method Injection sehe, ist Late-Binding, wenn eine Abhängigkeit bei der Controller-Konstruktion noch nicht bereit ist. Ansonsten ist es besser, Constructor Injection zu verwenden.
Ich sage das, weil bei Constructor Injection die Klasse bei der Konstruktion weiß, ob die Abhängigkeiten verfügbar sind. Bei Method Injection ist das nicht der Fall, es ist nicht bekannt, ob die Abhängigkeiten verfügbar sind, bis die Methode aufgerufen wird.
Autor: Chuck Conway ist spezialisiert auf Software-Engineering und Generative KI. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube.