Ich habe kürzlich das [FromServices]-Attribut entdeckt, das seit der ersten Version von .Net Core Teil des Frameworks 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 Methoden-Injection statt Constructor-Injection verwenden? Die häufige Erklärung ist, dass 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:
Meiner Meinung nach ist die Verwendung dieser Art von Methoden-Injection in Controller-Aktionen eine schlechte Idee, weil:
– Das
[FromServices]-Attribut kann leicht vergessen werden, und man erfährt davon erst, wenn die Aktion aufgerufen wird (statt beim Anwendungsstart, wo man die Konfiguration der Anwendung überprüfen kann)– Die Notwendigkeit, sich von Constructor-Injection aus Leistungsgründen abzuwenden, 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, sich von Constructor-Injection abzuwenden, um zu verhindern, dass Konstruktoren zu groß werden, ist ein Zeichen dafür, dass Ihre Klassen zu viele Abhängigkeiten haben und zu komplex werden. Mit anderen Worten: Viele Abhängigkeiten sind ein Zeichen dafür, dass die Klasse gegen das Single Responsibility Principle verstößt. 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ärent ist und daher ein Zeichen für einen SRP-Verstoß.
Statt das Grundproblem mit der Verwendung von Methoden-Injection zu verbergen, empfehle ich die Verwendung von Constructor-Injection als einziges Injektionsmuster hier und machen Sie Ihre Controller kleiner. Dies könnte jedoch bedeuten, dass sich Ihr Routing-Schema von Ihrer Klassenstruktur unterscheidet, aber das ist völlig in Ordnung und wird von ASP.NET Core vollständig unterstützt.
Aus Testbarkeitsperspektive sollte es eigentlich nicht wirklich wichtig sein, wenn es manchmal eine Abhängigkeit gibt, die nicht benötigt wird. Es gibt effektive Testmuster, die dieses Problem beheben.
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 verstoßen fast sicher gegen das SRP.
Der einzige Anwendungsfall, den ich bei Methoden-Injection sehe, ist Late-Binding, wenn eine Abhängigkeit bei der Controller-Konstruktion noch nicht verfügbar ist. Ansonsten ist es besser, Constructor-Injection zu verwenden.
Ich sage das, weil die Klasse bei Constructor-Injection bei der Konstruktion weiß, ob die Abhängigkeiten verfügbar sind. Bei Methoden-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 ein KI-Ingenieur mit fast 30 Jahren Erfahrung in der Softwareentwicklung. Er entwickelt praktische KI-Systeme – Content-Pipelines, Infrastruktur-Agenten und Tools, die echte Probleme lösen – und teilt seine Erkenntnisse unterwegs. Verbinden Sie sich mit ihm in den sozialen Medien: X (@chuckconway) oder besuchen Sie ihn auf YouTube und auf SubStack.