Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A .NET-ben a reflection API alapértelmezés szerint lehetővé teszi a fejlesztők számára a fő végrehajtási környezetbe betöltött szerelvények tartalmának vizsgálatát. Néha azonban nem lehet betölteni egy szerelvényt a végrehajtási környezetbe, például azért, mert egy másik platformra vagy processzorarchitektúrára állították össze, vagy egy referencia-szerelvény. Az System.Reflection.MetadataLoadContext API lehetővé teszi az ilyen szerelvények betöltését és vizsgálatát. A MetadataLoadContext-be betöltött szerelvények csak metaadatként kerülnek kezelésre, azaz megvizsgálhatja a szerelvény típusait, de nem hajthat végre benne semmilyen kódot. A fő végrehajtási környezettől eltérően a MetadataLoadContext rendszer nem tölti be automatikusan a függőségeket az aktuális könyvtárból, hanem az átadott könyvtár által MetadataAssemblyResolver biztosított egyéni kötési logikát használja.
Előfeltételek
A használatához MetadataLoadContexttelepítse a System.Reflection.MetadataLoadContext NuGet csomagot. Bármely .NET Standard 2.0-s szabványnak megfelelő cél-keretrendszerben támogatott, például .NET Core 2.0 vagy .NET Framework 4.6.1.
MetadataAssemblyResolver létrehozása MetadataLoadContexthez
MetadataLoadContext létrehozásához meg kell adni a MetadataAssemblyResolver példányát. A legegyszerűbb módja ennek az PathAssemblyResolver használata, amely a megadott szerelvényútvonal-sztringek gyűjteményéből oldja fel a szerelvényeket. Ennek a gyűjteménynek a közvetlenül vizsgálandó szerelvények mellett az összes szükséges függőséget is tartalmaznia kell. Például, ha egy külső assembly-ben található egyéni attribútumot szeretne elolvasni, vegye fel az assembly-t, különben kivételt okoz. A legtöbb esetben legalább az alapvető szerelvényt, vagyis a beépített rendszertípusokat tartalmazó szerelvényt kell tartalmaznia, például System.Object. Az alábbi kód bemutatja, hogyan hozhatja létre a PathAssemblyResolver a vizsgált szerelvényből és az aktuális futtatókörnyezet alapvető szerelvényéből álló gyűjtemény használatával.
var resolver = new PathAssemblyResolver(new string[] { "ExampleAssembly.dll", typeof(object).Assembly.Location });
Ha az összes BCL-típushoz hozzá kell férnie, az összes futtatókörnyezet-szerelvényt belefoglalhatja a gyűjteménybe. Az alábbi kód bemutatja, hogyan hozhatja létre a PathAssemblyResolver a vizsgált szerelvényből és az aktuális futtatókörnyezet összes szerelvényéből álló gyűjtemény használatával.
// Get the array of runtime assemblies.
string[] runtimeAssemblies = Directory.GetFiles(RuntimeEnvironment.GetRuntimeDirectory(), "*.dll");
// Create the list of assembly paths consisting of runtime assemblies and the inspected assembly.
var paths = new List<string>(runtimeAssemblies);
paths.Add("ExampleAssembly.dll");
// Create PathAssemblyResolver that can resolve assemblies using the created list.
var resolver = new PathAssemblyResolver(paths);
MetadataLoadContext létrehozása
A létrehozáshoz hívja meg a MetadataLoadContextkonstruktort MetadataLoadContext(MetadataAssemblyResolver, String), és adja át a korábban létrehozott MetadataAssemblyResolver paramétert első paraméterként, az alapvető szerelvény nevét pedig második paraméterként. Kihagyhatja az alapvető szerelvénynevet, amely esetben a konstruktor az alapértelmezett neveket próbálja használni: "mscorlib", "System.Runtime" vagy "netstandard".
A környezet létrehozása után az összeállításokat olyan módszerekkel töltheti be, mint a LoadFromAssemblyPath. Az összes tükrözési API-t használhatja a betöltött szerelvényeken, kivéve azokat, amelyek kódvégrehajtást igényelnek. A GetCustomAttributes metódus magában foglalja a konstruktorok végrehajtását, ezért használja inkább a GetCustomAttributesData metódust, amikor egyéni attribútumokat kell megvizsgálnia a MetadataLoadContext.
A következő kódminta létrehozza MetadataLoadContext, betölti a szerelvényt, és szerelvényattribútumokat ad ki a konzolon:
var mlc = new MetadataLoadContext(resolver);
using (mlc)
{
// Load assembly into MetadataLoadContext.
Assembly assembly = mlc.LoadFromAssemblyPath("ExampleAssembly.dll");
AssemblyName name = assembly.GetName();
// Print assembly attribute information.
Console.WriteLine($"{name.Name} has following attributes: ");
foreach (CustomAttributeData attr in assembly.GetCustomAttributesData())
{
try
{
Console.WriteLine(attr.AttributeType);
}
catch (FileNotFoundException ex)
{
// We are missing the required dependency assembly.
Console.WriteLine($"Error while getting attribute type: {ex.Message}");
}
}
}
Ha az egyenlőség vagy a hozzárendelhetőség szempontjából tesztelnie kell a MetadataLoadContext típusokat, csak az ebbe a környezetbe betöltött típusobjektumokat használja. A MetadataLoadContext típusok és a futatásidejű típusok keverése nem támogatott. Vegyünk például egy testedType típust a MetadataLoadContext-ben. Ha meg kell vizsgálnia, hogy egy másik típus rendelhető-e hozzá, ne használjon olyan kódot, mint a typeof(MyType).IsAssignableFrom(testedType). Használja a következőhöz hasonló kódot:
Assembly matchAssembly = mlc.LoadFromAssemblyPath(typeof(MyType).Assembly.Location);
Type matchType = assembly.GetType(typeof(MyType).FullName!)!;
if (matchType.IsAssignableFrom(testedType))
{
Console.WriteLine($"{nameof(matchType)} is assignable from {nameof(testedType)}");
}
Example
A teljes példakódért tekintse meg a szerelvény tartalmának vizsgálata MetadataLoadContext minta használatával című témakört.