Skip to content

Innlegg

Når skal du bruke FromService-attributten

20. november 2019 • 3 min lesing

Når skal du bruke FromService-attributten

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

Attributten [FromServices] tillater avhengighetsinjeksjon på metodnivå 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 metodinjeksjon fremfor konstruktørinjeksjon? Den vanlige forklaringen er når en metode trenger avhengigheter og den ikke brukes noe annet sted, så er den en kandidat for å bruke [FromService]-attributten.

Steven fra StackOverflow publiserte et svar mot bruk av [FromService]-attributten:

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

– Slik [FromServices]-attributt kan lett glemmes, og du vil bare finne ut når aksjonen blir påkalt (i stedet for å finne ut ved programstart, hvor du kan verifisere programmets konfigurasjon)

– Behovet for å gå bort fra konstruktørinjeksjon av ytelsesgrunner er en klar indikasjon på at injiserte komponenter er for tunge å opprette, mens injeksjonskonstruktører bør være enkle, og komponentopprettelse bør derfor være veldig lett.

– Behovet for å gå 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 er det å ha mange avhengigheter en indikasjon på at klassen bryter Single Responsibility Principle. Det faktum at kontrolleraksjoner dine enkelt kan deles opp over forskjellige klasser, er bevis på at en slik kontroller ikke er veldig sammenhengende, og derfor en indikasjon på et SRP-brudd.

Så i stedet for å skjule rotproblemet med bruken av metodinjeksjon, anbefaler jeg bruken av konstruktørinjeksjon som eneste injeksjonsmønster her og gjør kontrollerne dine mindre. Dette kan imidlertid bety at rutingsordningen din blir annerledes enn klassestrukturen din, men dette er helt greit og fullstendig støttet av ASP.NET Core.

Fra et testbarhets perspektiv, forresten, burde det egentlig ikke spille noen rolle hvis det noen ganger er en avhengighet som ikke er nødvendig. 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, så er det på tide å dele opp kontrolleren. Du bryter nesten helt sikkert SRP.

Det eneste brukstilfelle jeg ser med metodinjeksjon 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 metodinjeksjon er dette ikke tilfelle, det er ikke kjent om avhengighetene er tilgjengelige før metoden blir kalt.

Forfatter: Chuck Conway er en AI-ingeniør med nesten 30 års erfaring innen programvareutvikling. Han bygger praktiske AI-systemer—innholdspipelines, infrastrukturagenter og verktøy som løser virkelige problemer—og deler det han lærer underveis. Koble til ham på sosiale medier: X (@chuckconway) eller besøk ham på YouTube og på SubStack.

↑ Tilbake til toppen

Du kan også like