Skip to content

Innlegg

Når du skal bruke FromService-attributtet

20. november 2019 • 3 min lesing

Når du skal bruke FromService-attributtet

Jeg oppdaget nylig [FromServices]-attributtet, som har vært en del av .Net Core siden den første versjonen.

[FromServices]-attributtet tillater avhengighetsinjeksjon på metode-nivå i Asp.Net Core-kontrollere.

Her er et eksempel:

public class UserController : Controller
{
    private readonly IApplicationSettings _applicationSettings;

    public UserController(IApplicationSettings applicationSettings)
    {
        _applicationSettings = applicationSettings;
    }

    public IActionResult Get([FromService]IUserRepository userRepository, int userId)
    {
        //Do magic
    }
}

Hvorfor bruke metodeinjeksjon fremfor konstruktørinjeksjon? Den vanlige forklaringen er når en metode trenger avhengigheter og det ikke brukes andre steder, da er det en kandidat for å bruke [FromService]-attributtet.

Steven fra StackOverflow postet et svar mot å bruke [FromService]-attributtet:

For meg er bruken av denne typen metodeinjeksjon i kontrolleraksjoner en dårlig idé, fordi:

– Slike [FromServices]-attributter kan lett glemmes, og du vil bare finne ut av det når aksjonen blir påkalt (i stedet for å finne ut av det ved oppstart av applikasjonen, hvor du kan verifisere applikasjonens konfigurasjon)

– Behovet for å bevege seg bort fra konstruktørinjeksjon av ytelsesårsaker er en klar indikasjon på at injiserte komponenter er for tunge å opprette, mens injeksjonskonstruktører bør være enkle, og komponentoppretting bør derfor være svært lett.

– Behovet for å bevege seg bort fra konstruktørinjeksjon for å forhindre at konstruktører blir for store er en indikasjon på at klassene dine har for mange avhengigheter og blir for komplekse. Med andre ord, å ha mange avhengigheter er en indikasjon på at klassen bryter Single Responsibility Principle. Det faktum at kontrolleraksjoner lett kan deles over forskjellige klasser er bevis på at en slik kontroller ikke er særlig sammenhengende og derfor en indikasjon på et SRP-brudd.

Så i stedet for å skjule grunnproblemet med bruk av metodeinjeksjon, anbefaler jeg bruk av konstruktørinjeksjon som eneste injeksjonsmønster her og gjøre kontrollerne dine mindre. Dette kan imidlertid bety at rutingskjemaet ditt blir forskjellig fra klassestrukturen din, men dette er helt greit og fullstendig støttet av ASP.NET Core.

Fra et testbarhetsperspektiv, forresten, bør det egentlig ikke spille noen rolle om det noen ganger er en avhengighet som ikke trengs. Det finnes effektive testmønstre som løser dette problemet.

Jeg er enig med Steven; hvis du trenger å flytte avhengighetene dine fra kontrolleren til metoden fordi klassen konstruerer for mange avhengigheter, da er det på tide å dele opp kontrolleren. Du bryter nesten sikkert SRP.

Det eneste brukstilfellet jeg ser med metodeinjeksjon er sen binding når en avhengighet som ikke er klar ved kontrollerkonstruksjon. Ellers er det bedre å bruke konstruktørinjeksjon.

Jeg sier dette fordi med konstruktørinjeksjon vet klassen ved konstruksjon om avhengighetene er tilgjengelige. Med metodeinjeksjon er ikke dette tilfellet, det er ikke kjent om avhengighetene er tilgjengelige før metoden blir kalt.

Forfatter: Chuck Conway spesialiserer seg på programvareutvikling og Generativ AI. Koble til ham på sosiale medier: X (@chuckconway) eller besøk ham på YouTube.

↑ Tilbake til toppen

Du liker kanskje også