Beroenden

Det primära sättet att lägga till beroenden i ett .NET-bibliotek är att referera till NuGet-paket. Med NuGet-paketreferenser kan du snabbt återanvända och utnyttja redan skrivna funktioner, men de är en vanlig friktionskälla för .NET-utvecklare. Korrekt hantering av beroenden är viktigt för att förhindra att ändringar i andra .NET-bibliotek bryter mot .NET-biblioteket och vice versa!

Diamantberoenden

Det är vanligt att ett .NET-projekt har flera versioner av ett paket i sitt beroendeträd. En app är till exempel beroende av två NuGet-paket, som var och en är beroende av en annan version av samma paket. Det finns nu ett diamantberoende i appens beroendediagram.

Diamond dependency

Vid bygget analyserar NuGet alla paket som ett projekt är beroende av, inklusive beroenden av beroenden. När flera versioner av ett paket identifieras utvärderas regler för att välja en. Det är nödvändigt att förena paket eftersom det är problematiskt att köra sida vid sida-versioner av en sammansättning i samma program i .NET.

De flesta rombberoenden är lätta att lösa. De kan dock skapa problem under vissa omständigheter:

  • NuGet-paketreferenser i konflikt förhindrar att en version löses under paketåterställningen.
  • Icke-bakåtkompatibla ändringar mellan versionerna orsakar buggar och undantag vid körning.
  • Paketsammansättningen är stark med namnet, sammansättningsversionen har ändrats och appen körs på .NET Framework. Omdirigeringar av sammansättningsbindningar krävs.

Det går inte att veta vilka paket som ska användas tillsammans med dina egna. Ett bra sätt att minska sannolikheten för att ett diamantberoende bryter biblioteket är att minimera antalet paket som du är beroende av.

✔️ Granska .NET-biblioteket för onödiga beroenden.

NuGet-beroendeversionsintervall

En paketreferens anger det intervall med giltiga paket som tillåts. Vanligtvis är paketreferensversionen i projektfilen den lägsta versionen och det finns inget maximum.

<!-- Accepts any version 1.0 and above. -->
<PackageReference Include="ExamplePackage" Version="1.0" />

De regler som NuGet använder när du löser beroenden är komplexa, men NuGet söker som standard efter den lägsta tillämpliga versionen. NuGet föredrar den lägsta tillämpliga versionen framför att använda den högsta tillgängliga versionen eftersom den lägsta har minst kompatibilitetsproblem.

På grund av NuGets lägsta tillämpliga versionsregel är det inte nödvändigt att placera en övre version eller ett exakt intervall på paketreferenser för att undvika att få den senaste versionen. NuGet försöker redan hitta den lägsta och mest kompatibla versionen åt dig.

<!-- Accepts 1.0 up to 1.x, but not 2.0 and higher. -->
<PackageReference Include="ExamplePackage" Version="[1.0,2.0)" />

<!-- Accepts exactly 1.0. -->
<PackageReference Include="ExamplePackage" Version="[1.0]" />

Övre versionsgränser gör att NuGet misslyckas om det finns en konflikt. Ett bibliotek accepterar till exempel exakt 1,0 medan ett annat bibliotek kräver 2.0 eller senare. Icke-bakåtkompatibla ändringar kan ha införts i version 2.0, men ett strikt eller övre gränsversionsberoende garanterar ett fel.

Diamond dependency conflict

❌ Ha INTE NuGet-paketreferenser utan minsta version.

❌ UNDVIK NuGet-paketreferenser som kräver en exakt version.

❌ UNDVIK NuGet-paketreferenser med en övre version.

Mer information finns i Paketversioner.

NuGet-paket för delad källa

Ett sätt att minska externa Beroenden för NuGet-paket är att referera till paket med delad källa. Ett delat källpaket innehåller källkodsfiler som ingår i ett projekt när de refereras. Eftersom du bara inkluderar källkodsfiler som kompileras med resten av projektet finns det inget externt beroende och risk för konflikter.

Paket med delad källa är bra för att inkludera små funktioner. Du kan till exempel referera till ett paket med hjälpmetoder för delad källa för att göra HTTP-anrop.

Shared source package

<PackageReference Include="Microsoft.Extensions.Buffers.Testing.Sources" PrivateAssets="All" Version="1.0" />

Shared source project

Paket med delad källa har vissa begränsningar. De kan bara refereras till av PackageReference, så äldre packages.config projekt exkluderas. Dessutom kan delade källpaket endast användas av projekt med samma språk. På grund av dessa begränsningar används paket med delad källkod bäst för att dela funktioner i ett projekt med öppen källkod.

✔️ ÖVERVÄG att referera till paket med delad källkod för små, interna funktioner.

✔️ ÖVERVÄG att göra ditt paket till ett paket med delad källa om det innehåller små, interna funktioner.

✔️ DO refererar till delade källpaket med PrivateAssets="All".

Den här inställningen anger att NuGet-paketet endast ska användas vid utvecklingstidpunkt och inte ska exponeras som ett offentligt beroende.

❌ HA INTE pakettyper för delad källa i ditt offentliga API.

Delade källtyper kompileras till referenssammansättningen och kan inte utbytas över sammansättningsgränser. En typ av delad källa IRepository i ett projekt är till exempel en separat typ från samma delade källa IRepository i ett annat projekt. Typer i paket med delad källa bör ha en internal synlighet.

❌ PUBLICERA INTE paket med delad källa till NuGet.org.

Paket med delad källkod innehåller källkod och kan endast användas av projekt med samma språktyp. Ett delat C#-källpaket kan till exempel inte användas av ett F#-program.

Publicera delade källpaket till ett lokalt flöde eller MyGet för att använda dem internt i projektet.