Aracılığıyla paylaş


Nasıl yapılır: MetadataLoadContext kullanarak derleme içeriğini inceleme

.NET'teki yansıma API'si varsayılan olarak geliştiricilerin ana yürütme bağlamı içine yüklenen derlemelerin içeriğini incelemesine olanak tanır. Ancak, örneğin başka bir platform veya işlemci mimarisi için derlendiğinden veya bir başvuru derlemesi olduğundan, bazen yürütme bağlamı içine bir derleme yüklemek mümkün değildir. API, System.Reflection.MetadataLoadContext bu tür derlemeleri yüklemenize ve incelemenize olanak tanır. içine MetadataLoadContext yüklenen derlemeler yalnızca meta veri olarak kabul edilir, yani derlemedeki türleri inceleyebilirsiniz, ancak içinde bulunan herhangi bir kodu yürütemezsiniz. Ana yürütme bağlamından farklı olarak , MetadataLoadContext geçerli dizinden bağımlılıkları otomatik olarak yüklemez; bunun yerine, geçirilen tarafından MetadataAssemblyResolver sağlanan özel bağlama mantığını kullanır.

Önkoşullar

kullanmak MetadataLoadContextiçin System.Düşünceler yükleyin Iyon. MetadataLoadContext NuGet paketi. .NET Core 2.0 veya .NET Framework 4.6.1 gibi tüm .NET Standard 2.0 uyumlu hedef çerçevelerde desteklenir.

MetadataLoadContext için MetadataAssemblyResolver oluşturma

öğesini oluşturmak MetadataLoadContext için örneğinin MetadataAssemblyResolversağlanması gerekir. Sağlamanın en basit yolu, verilen derleme yolu dizeleri koleksiyonundaki derlemeleri çözümleyen öğesini kullanmaktır PathAssemblyResolver. Bu koleksiyon, doğrudan incelemek istediğiniz derlemelerin yanı sıra tüm gerekli bağımlılıkları da içermelidir. Örneğin, bir dış derlemede bulunan özel özniteliği okumak için bu derlemeyi eklemeniz gerekir, aksi takdirde bir özel durum oluşturulur. Çoğu durumda, en azından çekirdek derlemeyi, yani gibi System.Objectyerleşik sistem türlerini içeren derlemeyi eklemeniz gerekir. Aşağıdaki kod, incelenen derleme ve geçerli çalışma zamanının çekirdek derlemesini içeren koleksiyonu kullanarak öğesinin nasıl oluşturulacağını PathAssemblyResolver gösterir:

var resolver = new PathAssemblyResolver(new string[] { "ExampleAssembly.dll", typeof(object).Assembly.Location });

Tüm BCL türlerine erişmeniz gerekiyorsa, tüm çalışma zamanı derlemelerini koleksiyona ekleyebilirsiniz. Aşağıdaki kod, denetlenen derlemeden ve geçerli çalışma zamanının tüm derlemelerinden oluşan koleksiyonu kullanarak öğesinin nasıl oluşturulacağını PathAssemblyResolver gösterir:

// 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 Oluşturma

oluşturmak MetadataLoadContextiçin oluşturucusunu MetadataLoadContext(MetadataAssemblyResolver, String)çağırın ve daha önce oluşturulan MetadataAssemblyResolver ilk parametreyi ve çekirdek derleme adını ikinci parametre olarak geçirin. Çekirdek derleme adını atlayabilirsiniz; bu durumda oluşturucu varsayılan adları kullanmayı dener: "mscorlib", "System.Runtime" veya "netstandard".

Bağlamı oluşturduktan sonra, gibi LoadFromAssemblyPathyöntemleri kullanarak içine derlemeler yükleyebilirsiniz. Kod yürütmeyi içeren derlemeler dışında yüklü derlemelerde tüm yansıma API'lerini kullanabilirsiniz. GetCustomAttributes yöntemi oluşturucuların yürütülmesini içerir, bu nedenle içindeki özel öznitelikleri MetadataLoadContextincelemeniz gerektiğinde bunun yerine yöntemini kullanınGetCustomAttributesData.

Aşağıdaki kod örneği oluşturur MetadataLoadContext, derlemeyi içine yükler ve derleme özniteliklerini konsoluna gönderir:

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}");
        }
    }
}

eşitlik veya atanabilirlik için içindeki MetadataLoadContext türleri test etmeniz gerekiyorsa, yalnızca bu bağlama yüklenen tür nesnelerini kullanın. Türlerin çalışma zamanı türleriyle karıştırılması MetadataLoadContext desteklenmez. Örneğin, içinde MetadataLoadContextbir tür testedType düşünün. Başka bir türün atanıp atanamayacağını test etmeniz gerekiyorsa, gibi typeof(MyType).IsAssignableFrom(testedType)bir kod kullanmayın. Bunun yerine aşağıdaki gibi bir kod kullanın:

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)}");
}

Örnek

Eksiksiz bir kod örneği için MetadataLoadContext kullanarak derleme içeriğini inceleme örneğine bakın.

Ayrıca bkz.