|
1 | 1 | --- |
2 | 2 | title: About AssemblyLoadContext - .NET |
3 | 3 | description: Key concepts to understand the purpose and behavior of AssemblyLoadContext in .NET. |
4 | | -ms.date: 08/18/2022 |
| 4 | +ms.date: 03/05/2026 |
5 | 5 | author: sdmaclea |
| 6 | +ai-usage: ai-assisted |
6 | 7 | --- |
7 | 8 | # About System.Runtime.Loader.AssemblyLoadContext |
8 | 9 |
|
@@ -109,3 +110,52 @@ There are two design patterns for solving these type conversion issues. |
109 | 110 | 1. Use common shared types. This shared type can either be a primitive runtime type, or it can involve creating a new shared type in a shared assembly. Often the shared type is an [interface](../../csharp/language-reference/keywords/interface.md) defined in an application assembly. For more information, read about [how dependencies are shared](#shared-dependencies). |
110 | 111 |
|
111 | 112 | 2. Use marshalling techniques to convert from one type to another. |
| 113 | + |
| 114 | +## Access static members |
| 115 | + |
| 116 | +Types loaded into a custom <xref:System.Runtime.Loader.AssemblyLoadContext> are isolated from types in other contexts, so you must use reflection to access their static members from outside the context. |
| 117 | + |
| 118 | +For example, consider this static class in a dynamically loaded assembly: |
| 119 | + |
| 120 | +```csharp |
| 121 | +namespace MyPlugin; |
| 122 | + |
| 123 | +public static class Paths |
| 124 | +{ |
| 125 | + public static DirectoryInfo RootIO { get; private set; } |
| 126 | +} |
| 127 | +``` |
| 128 | + |
| 129 | +Use <xref:System.Reflection.PropertyInfo.GetValue%2A?displayProperty=nameWithType> to read the property value. Pass `null` as the first argument because static members don't require an instance. Pass the fully qualified type name (including the namespace) to <xref:System.Reflection.Assembly.GetType(System.String)?displayProperty=nameWithType>: |
| 130 | + |
| 131 | +```csharp |
| 132 | +// Get the type from the loaded assembly using the fully qualified name |
| 133 | +Type pathsType = loadedAssembly.GetType("MyPlugin.Paths") |
| 134 | + ?? throw new InvalidOperationException("Type 'MyPlugin.Paths' not found in loaded assembly."); |
| 135 | + |
| 136 | +// Use PropertyInfo to access a static property |
| 137 | +PropertyInfo rootIoProperty = pathsType.GetProperty("RootIO") |
| 138 | + ?? throw new InvalidOperationException("Property 'RootIO' was not found on type 'MyPlugin.Paths'."); |
| 139 | +DirectoryInfo rootIo = (DirectoryInfo)rootIoProperty.GetValue(null); |
| 140 | +``` |
| 141 | + |
| 142 | +Alternatively, C# compiles property accessors into methods with `get_` and `set_` prefixes. You can call these accessor methods directly using <xref:System.Type.GetMethod%2A?displayProperty=nameWithType>. However, <xref:System.Type.GetMethod(System.String)?displayProperty=nameWithType> only returns public methods. When an accessor is non-public (such as the `private set` in the example), you must use the overload that accepts <xref:System.Reflection.BindingFlags>: |
| 143 | + |
| 144 | +```csharp |
| 145 | +// Public getter — no BindingFlags needed |
| 146 | +MethodInfo getRootIo = pathsType.GetMethod("get_RootIO") |
| 147 | + ?? throw new InvalidOperationException("Accessor method 'get_RootIO' was not found on type 'MyPlugin.Paths'."); |
| 148 | +DirectoryInfo rootIo = (DirectoryInfo)getRootIo.Invoke(null, null); |
| 149 | + |
| 150 | +// Non-public setter — must use BindingFlags |
| 151 | +MethodInfo setRootIo = pathsType.GetMethod( |
| 152 | + "set_RootIO", |
| 153 | + BindingFlags.Static | BindingFlags.NonPublic) |
| 154 | + ?? throw new InvalidOperationException("Accessor method 'set_RootIO' was not found on type 'MyPlugin.Paths'."); |
| 155 | +setRootIo.Invoke(null, new object[] { newValue }); |
| 156 | +``` |
| 157 | + |
| 158 | +The same pattern applies to static fields, which you can access via <xref:System.Reflection.FieldInfo.GetValue%2A?displayProperty=nameWithType> and <xref:System.Reflection.FieldInfo.SetValue%2A?displayProperty=nameWithType>, and to static methods, which you invoke with <xref:System.Reflection.MethodBase.Invoke%2A?displayProperty=nameWithType>. |
| 159 | + |
| 160 | +> [!NOTE] |
| 161 | +> If you retrieve a value whose type is defined in the loaded assembly, you might encounter type-conversion issues when you try to cast it in the calling context. For more information, see [Type-conversion issues](#type-conversion-issues). |
0 commit comments