Dela via


Så här letar Runtime upp sammansättningar

Anmärkning

Den här artikeln är specifik för .NET Framework. Det gäller inte för nyare implementeringar av .NET, inklusive .NET 6 och senare versioner.

Om du vill distribuera .NET Framework-programmet måste du förstå hur den vanliga språkkörningen hittar och binder till de sammansättningar som utgör ditt program. Som standardinställning försöker körmiljön binda med den exakta versionen av en assembly som programmet byggdes med. Det här standardbeteendet kan åsidosättas av konfigurationsfilens inställningar.

Den vanliga språkkörningen utför ett antal steg när du försöker hitta en sammansättning och lösa en sammansättningsreferens. Varje steg beskrivs i följande avsnitt. Termen "undersökning" används ofta när man beskriver hur körtiden hittar samlingar. Den hänvisar till den uppsättning heuristiker som används för att lokalisera samlingen baserat på dess namn och kulturell inställning.

Anmärkning

Du kan visa bindningsinformation i loggfilen med hjälp av loggboken för sammansättningsbindning (Fuslogvw.exe), som ingår i Windows SDK.

Initiera bindningen

Processen för att hitta och binda till en assembly börjar när körtiden försöker lösa en referens till en annan assembly. Den här referensen kan vara antingen statisk eller dynamisk. Kompilatorn registrerar statiska referenser i sammansättningsmanifestets metadata vid byggtiden. Dynamiska referenser skapas i farten som ett resultat av att anropa olika metoder, till exempel Assembly.Load.

Det bästa sättet att referera till en sammansättning är att använda en fullständig referens, inklusive sammansättningsnamn, version, kultur och offentlig nyckeltoken (om det finns någon). Körningen använder den här informationen för att hitta sammansättningen, enligt stegen som beskrivs senare i det här avsnittet. Körtiden använder samma lösningsprocess oavsett om referensen är för en statisk eller dynamisk assembly.

Du kan också göra en dynamisk referens till en sammansättning genom att ange anropsmetoden med endast partiell information om sammansättningen, till exempel att endast ange sammansättningsnamnet. I det här fallet söks endast programkatalogen efter sammansättningen och ingen annan kontroll utförs. Du gör en partiell referens med någon av de olika metoderna för att läsa in sammansättningar, till exempel Assembly.Load eller AppDomain.Load.

Slutligen kan du göra en dynamisk referens med hjälp av en metod som Assembly.Load och endast ange partiell information. Sedan kvalificerar du referensen med elementet <qualifyAssembly> i programkonfigurationsfilen. Med det här elementet kan du ange fullständig referensinformation (namn, version, kultur och, om tillämpligt, token för offentlig nyckel) i programkonfigurationsfilen i stället för i koden. Du skulle använda den här tekniken om du vill kvalificera en referens till en sammansättning utanför programkatalogen, eller om du vill referera till en sammansättning i den globala sammansättningscache men du vill ha bekvämligheten med att ange den fullständiga referensen i konfigurationsfilen i stället för i koden.

Anmärkning

Den här typen av partiell referens bör inte användas med sammansättningar som delas mellan flera program. Eftersom konfigurationsinställningarna tillämpas per program och inte per sammansättning, skulle en delad sammansättning som använder den här typen av partiell referens kräva att varje program som använder den delade sammansättningen har kvalificerande information i sin konfigurationsfil.

Körningen använder följande steg för att lösa en sammansättningsreferens:

  1. Avgör rätt sammansättningsversion genom att undersöka tillämpliga konfigurationsfiler, inklusive programkonfigurationsfilen, utgivarens principfil och datorkonfigurationsfilen. Om konfigurationsfilen finns på en fjärrdator måste körningen leta upp och ladda ned programkonfigurationsfilen först.

  2. Kontrollerar om sammansättningsnamnet har bundits till tidigare och använder i så fall den tidigare inlästa sammansättningen. Om en tidigare begäran om att läsa in sammansättningen misslyckades, misslyckas begäran omedelbart utan att försöka läsa in sammansättningen.

    Anmärkning

    Cachelagringen av sammansättningsbindningsfel är ny i .NET Framework version 2.0.

  3. Kontrollerar den globala sammansättningscachen. Om sammansättningen hittas där använder körningen den här sammansättningen.

  4. Sonder för montering med hjälp av följande steg:

    1. Om konfigurations- och utgivarprinciper inte påverkar den ursprungliga referensen och om bindningsbegäran skapades med metoden Assembly.LoadFrom, söker runtime-miljön efter platsanvisningar.

    2. Om en kodbas hittas i konfigurationsfilerna kontrollerar körningstiden endast denna plats. Om den här avsökningen misslyckas avgör körtiden att bindningsbegäran misslyckades och ingen annan avsökning sker.

    3. Avsökningar för sammansättningen med hjälp av heuristiken som beskrivs i avsökningsavsnittet. Om samlingen inte hittas efter avsökningen, begär körmiljön att Windows Installer tillhandahåller samlingen. Detta fungerar som en funktion för installation på begäran.

      Anmärkning

      Det finns ingen versionskontroll för sammansättningar utan starka namn, och inte heller kontrollerar körningen den globala sammansättningscachen för sammansättningar utan starka namn.

Steg 1: Undersöka konfigurationsfilerna

Sammansättningsbindningsbeteende kan konfigureras på olika nivåer baserat på tre XML-filer:

  • Programkonfigurationsfil.

  • Policyfil för utgivare.

  • Datorkonfigurationsfil.

Dessa filer följer samma syntax och innehåller information som bindningsomdirigeringar, platsen för kod och bindningslägen för specifika sammansättningar. Varje konfigurationsfil kan innehålla ett <assemblyBinding-element> som omdirigerar bindningsprocessen. De underordnade elementen i <assemblyBinding-elementet> inkluderar <dependentAssembly-elementet>. <Underordnade element för dependentAssembly-elementet><är assemblyIdentity-elementet>, <bindingRedirect-elementet> och <codeBase-elementet>.

Anmärkning

Konfigurationsinformation finns i de tre konfigurationsfilerna. alla element är inte giltiga i alla konfigurationsfiler. Till exempel kan bindningsläge och information om privat sökväg endast finnas i programkonfigurationsfilen. En fullständig lista över den information som finns i varje fil finns i Konfigurera appar med hjälp av konfigurationsfiler.

Konfigurationsfil för program

För det första kontrollerar den vanliga språkkörningen programkonfigurationsfilen för information som åsidosätter versionsinformationen som lagras i den anropande sammansättningens manifest. Programkonfigurationsfilen kan distribueras med ett program, men krävs inte för programkörning. Vanligtvis är hämtningen av den här filen nästan omedelbar, men i situationer där programbasen finns på en fjärrdator, till exempel i ett webbaserat scenario, måste konfigurationsfilen laddas ned.

För körbara klienter finns programkonfigurationsfilen i samma katalog som programmets körbara fil och har samma basnamn som den körbara filen med ett .config-tillägg. Konfigurationsfilen för C:\Program Files\Myapp\Myapp.exe är till exempel C:\Program Files\Myapp\Myapp.exe.config. I ett webbläsarbaserat scenario måste HTML-filen använda <länkelementet> för att uttryckligen peka på konfigurationsfilen.

Följande kod innehåller ett enkelt exempel på en programkonfigurationsfil. Det här exemplet lägger till en TextWriterTraceListener i Listeners-samlingen för att möjliggöra inspelning av felsökningsinformation i en fil.

<configuration>
   <system.diagnostics>
      <trace useGlobalLock="false" autoflush="true" indentsize="0">
         <listeners>
            <add name="myListener" type="System.Diagnostics.TextWriterTraceListener, system version=1.0.3300.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" initializeData="c:\myListener.log" />
         </listeners>
      </trace>
   </system.diagnostics>
</configuration>

Principfil för utgivare

För det andra undersöker körmiljön utgivarprincipfilen, om en sådan finns. Utgivarprincipfiler distribueras av en komponentutgivare som en korrigering eller uppdatering av en delad komponent. Dessa filer innehåller kompatibilitetsinformation som utfärdats av utgivaren av den delade komponenten som dirigerar en sammansättningsreferens till en ny version. Till skillnad från program- och maskinkonfigurationsfiler, finns utgivarpolicyfilerna i en egen assembly som måste installeras i den globala assemblycachen.

Följande är ett exempel på en konfigurationsfil för Publisher Policy:

<configuration>
    <runtime>
        <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">

            <dependentAssembly>
                <assemblyIdentity name="asm6" publicKeyToken="c0305c36380ba429" />
                <bindingRedirect oldVersion="3.0.0.0" newVersion="2.0.0.0"/>
            </dependentAssembly>

        </assemblyBinding>
    </runtime>
</configuration>

Om du vill skapa en sammansättning kan du använda verktyget Al.exe (Assembly Linker) med ett kommando, till exempel följande:

Al.exe /link:asm6.exe.config /out:policy.3.0.asm6.dll /keyfile: compatkey.dat /v:3.0.0.0

compatkey.dat är en nyckelfil med starkt namn. Det här kommandot skapar en starknamngiven sammansättning som du kan placera i den globala sammansättningscachen.

Anmärkning

Utgivarprincipen påverkar alla program som använder en delad komponent.

Konfigurationsfilen för utgivarprincip åsidosätter versionsinformation som kommer från programmet (det vill: från sammansättningsmanifestet eller från programkonfigurationsfilen). Om det inte finns någon instruktion i programkonfigurationsfilen för att omdirigera den version som anges i sammansättningsmanifestet åsidosätter utgivarens principfil den version som anges i sammansättningsmanifestet. Men om det finns en omdirigeringssats i programkonfigurationsfilen åsidosätter utgivarprincipen den versionen i stället för den som anges i manifestet.

En utgivarprincipfil används när en delad komponent uppdateras och den nya versionen av den delade komponenten ska hämtas av alla program som använder komponenten. Inställningarna i utgivarprincipfilen åsidosätter inställningarna i programkonfigurationsfilen, såvida inte programkonfigurationsfilen kräver felsäkert läge.

Säkert läge

Utgivarpolicyfiler installeras vanligtvis som en del av ett servicetillägg eller programuppdatering. Om det uppstår problem med den uppgraderade delade komponenten kan du ignorera åsidosättningarna i utgivarprincipfilen med säkert läge. Felsäkert läge bestäms av elementet <publisherPolicy apply="yes|no"/> , som endast finns i programkonfigurationsfilen. Den anger huruvida konfigurationsinformationen för utgivarens policy ska tas bort från bindningsprocessen.

Felsäkert läge kan ställas in för hela programmet eller för valda sammansättningar. Du kan alltså inaktivera principen för alla sammansättningar som utgör programmet eller aktivera den för vissa sammansättningar, men inte för andra. Om du vill tillämpa utgivarprincipen selektivt på sammansättningar som utgör ett program, ställ in <publisherPolicy apply=no/> och specificera vilka sammansättningar som ska påverkas med hjälp av <beroendeSammansättning-elementet>. Om du vill tillämpa utgivarprincip på alla sammansättningar som utgör programmet anger du <publisherPolicy apply=no/> utan beroende sammansättningselement. Mer information om konfiguration finns i Konfigurera appar med hjälp av Konfigurationsfiler.

Datorkonfigurationsfil

För det tredje undersöker körningstiden datorkonfigurationsfilen. Den här filen, som heter Machine.config, finns på den lokala datorn i underkatalogen Config i rotkatalogen där runtime-miljön är installerad. Den här filen kan användas av administratörer för att ange begränsningar för sammansättningsbindning som är lokala för den datorn. Inställningarna i datorkonfigurationsfilen har företräde framför alla andra konfigurationsinställningar. Detta innebär dock inte att alla konfigurationsinställningar ska placeras i den här filen. Den version som bestäms av administratörsprincipfilen är slutgiltig och kan inte åsidosättas. Inställningar som anges i filen Machine.config påverkar alla program. Mer information om konfigurationsfiler finns i Konfigurera appar med hjälp av Konfigurationsfiler.

Steg 2: Söka efter tidigare refererade sammansättningar

Om den begärda sammansättningen också har begärts i tidigare anrop använder common language runtime den sammansättning som redan har lästs in. Detta kan få konsekvenser när du namnger sammansättningar som utgör ett program. Mer information om namngivningssammansättningar finns i Sammansättningsnamn.

Om en tidigare begäran om komponenten misslyckades, misslyckas efterföljande begäranden för komponenten omedelbart utan att försöka läsa in komponenten. Från och med .NET Framework version 2.0 cachelagras sammansättningsbindningsfel och cachelagrad information används för att avgöra om sammansättningen ska läsas in.

Anmärkning

Om du vill återgå till beteendet för .NET Framework-versionerna 1.0 och 1.1, som inte cachelagrade bindningsfel, inkluderar du elementet< disableCachingBindingFailures> i konfigurationsfilen.

Steg 3: Kontrollerar den globala sammansättningscachen

För starka namngivna sammansättningar fortsätter bindningsprocessen genom att titta i den globala sammansättningscachen. Den globala sammansättningscachen lagrar sammansättningar som kan användas av flera program på en dator. Alla sammansättningar i den globala sammansättningscachen måste ha starka namn.

Steg 4: Hitta sammansättningen via kodbaser eller avsökning

När rätt sammansättningsversion har fastställts med hjälp av informationen i referensen för den anropande sammansättningen och konfigurationsfilerna, och efter att den har kontrollerats i den globala sammansättningscache (endast för starkt namngivna sammansättningar), försöker den gemensamma språkkörningen (CLR) hitta sammansättningen. Processen för att hitta en sammansättning omfattar följande steg:

  1. Om ett <codeBase-element> hittas i programkonfigurationsfilen kontrollerar körningen den angivna platsen. Om en matchning hittas används den sammansättningen och ingen avsökning sker. Om sammansättningen inte hittas där misslyckas bindningsbegäran.

  2. Programmiljön söker sedan efter den refererade assemblyn med hjälp av de regler som anges senare i det här avsnittet.

Anmärkning

Om du har flera versioner av en sammansättning i en katalog och vill referera till en viss version av sammansättningen måste du använda <codeBase-elementet> i stället för privatePath attributet för <avsökningselementet> . Om du använder <avsökningselementet> slutar körningen att avsökningen första gången den hittar en sammansättning som matchar det enkla sammansättningsnamnet som refereras, oavsett om det är en korrekt matchning eller inte. Om det är en korrekt matchning används den sammansättningen. Om det inte är en korrekt matchning misslyckas avsökningen och bindningen misslyckas.

Hitta sammansättningen via Codebases

Codebase-information kan tillhandahållas med hjälp av ett <codeBase-element> i en konfigurationsfil. Den här kodbasen kontrolleras alltid innan körningen försöker söka efter den refererade assemblyn. Om en utgivarprincipfil som innehåller den slutliga versionsomdirigeringen också innehåller ett <codeBase-element> är det codeBase-elementet<> det som används. Om din programkonfigurationsfil till exempel anger ett <codeBase-element> och en utgivarprincipfil som åsidosätter programinformationen även anger ett <codeBase-element> , <används codeBase-elementet> i utgivarprincipfilen.

Om ingen matchning hittas på den plats som anges av <codeBase-elementet> misslyckas bindningsbegäran och inga ytterligare åtgärder vidtas. Om körmiljön avgör att en assembly matchar den anropande assemblyns kriterier, använder den den assemblyn. När filen som anges av det angivna <codeBase-elementet> läses in kontrollerar körmiljön att namnet, versionen, kulturen och den offentliga nyckeln stämmer överens med referensen för den anropande sammansättningen.

Anmärkning

Refererade sammansättningar utanför programmets rotmapp måste ha starka namn och måste antingen installeras i den globala sammansättningscache eller anges genom <codeBase-elementet>.

Hitta sammansättningen genom avsökning

Om det inte finns något <codeBase-element> i programkonfigurationsfilen avsöker runtime-avsökningarna för sammansättningen med hjälp av fyra villkor:

  • Programbas, som är den rotplats där programmet körs.

  • Kultur, som är kulturattributet för sammansättningen som refereras till.

  • Namn, som är namnet på den refererade sammansättningen.

  • Attributet privatePath för <avsökningselementet>, som är den användardefinierade listan över underkataloger i rotkatalogen. Den här platsen kan anges i programkonfigurationsfilen och i hanterad kod med hjälp av AppDomainSetup.PrivateBinPath egenskapen för en programdomän. När den har angetts i hanterad kod avsöks den hanterade koden privatePath först, följt av sökvägen som anges i programkonfigurationsfilen.

Avsökning av programbasen och kulturkatalogerna

Körningen börjar alltid avsökning i programmets bas, vilket kan vara antingen en URL eller programmets rotkatalog på en dator. Om den refererade sammansättningen inte hittas i programbasen och ingen kulturell information tillhandahålls, genomsöker körmiljön eventuella underkataloger med sammansättningsnamnet. De kataloger som avsöks är:

  • [programbas] / [sammansättningsnamn].dll

  • [programbas] / [sammansättningsnamn] / [sammansättningsnamn].dll

Om kulturinformation anges för den refererade sammansättningen avsöks endast följande kataloger:

  • [programbas] / [kultur] / [sammansättningsnamn].dll

  • [programbas] / [kultur] / [sammansättningsnamn] / [sammansättningsnamn].dll

Avsökning med privatePath-attributet

Förutom kulturunderkatalogerna och underkatalogerna som är namngivna efter den refererade sammansättningen, avsöker runtime även kataloger som anges med privatePath-attributet hos <avsökning> elementet. De kataloger som anges med attributet privatePath måste vara underkataloger till programmets rotkatalog. De kataloger som avsöks varierar beroende på om kulturinformation ingår i den refererade sammansättningsbegäran.

Körmiljön slutar avsökningen första gången den hittar en assembly som matchar det refererade enkla assemblynamnet, oavsett om det är en korrekt matchning eller inte. Om det är en korrekt matchning används den sammansättningen. Om det inte är en korrekt matchning misslyckas avsökningen och bindningen misslyckas.

Om kultur ingår avsöks följande kataloger:

  • [programbas] / [binpath] / [kultur] / [sammansättningsnamn].dll

  • [programbas] / [binpath] / [kultur] / [assemblenamn] / [assemblenamn].dll

Om kulturinformation inte ingår avsöks följande kataloger:

  • [programbas] / [binpath] / [sammansättningsnamn].dll

  • [programbas] / [binpath] / [assemblenamn] / [assemblenamn].dll

Exempel på avsökning

Med följande information:

  • Refererat sammansättningsnamn: myAssembly

  • Applikationsrotkatalog: http://www.code.microsoft.com

  • <avsökningselement> i konfigurationsfilen anger: bin

  • Kultur: de

Körningstiden undersöker följande URL:er:

  • http://www.code.microsoft.com/de/myAssembly.dll

  • http://www.code.microsoft.com/de/myAssembly/myAssembly.dll

  • http://www.code.microsoft.com/bin/de/myAssembly.dll

  • http://www.code.microsoft.com/bin/de/myAssembly/myAssembly.dll

Flera sammansättningar med samma namn

I följande exempel visas hur du konfigurerar flera sammansättningar med samma namn.

<dependentAssembly>
   <assemblyIdentity name="Server" publicKeyToken="c0305c36380ba429" />
   <codeBase version="1.0.0.0" href="v1/Server.dll" />
   <codeBase version="2.0.0.0" href="v2/Server.dll" />
</dependentAssembly>

Andra undersökta platser

Sammansättningsplats kan också fastställas med hjälp av den aktuella bindningskontexten. Detta inträffar oftast när Assembly.LoadFrom metoden används och i COM-interopscenarier. Om en sammansättning använder LoadFrom metoden för att referera till en annan sammansättning anses den anropande sammansättningens plats vara ett tips om var den refererade sammansättningen finns. Om en matchning hittas, laddas assemblaget. Om ingen matchning hittas fortsätter körningen med dess söksemantik och frågar sedan Windows Installer för att tillhandahålla sammansättningen. Om det inte finns någon sammansättning som matchar bindningsbegäran genereras ett undantag. Det här undantaget är en TypeLoadException i hanterad kod om en typ refererades, eller en FileNotFoundException om en assembly som lästes in inte hittades.

Om assembly1 till exempel refererar till Assembly2 och Assembly1 laddades ned från http://www.code.microsoft.com/utilsanses platsen vara ett tips om var du hittar Assembly2.dll. Körmiljön söker sedan efter samlingen i http://www.code.microsoft.com/utils/Assembly2.dll och http://www.code.microsoft.com/utils/Assembly2/Assembly2.dll. Om Assembly2 inte hittas på någon av dessa platser undersöker körtillståndet Windows Installer.

Se även