Classe System.Runtime.Loader.AssemblyLoadContext
Cet article vous offre des remarques complémentaires à la documentation de référence pour cette API.
Représente AssemblyLoadContext un contexte de chargement. Conceptuellement, un contexte de chargement crée une étendue pour le chargement, la résolution et le déchargement d’un ensemble d’assemblys.
Il AssemblyLoadContext existe principalement pour fournir une isolation de chargement d’assembly. Il permet à plusieurs versions du même assembly d’être chargées dans un seul processus. Il remplace les mécanismes d’isolation fournis par plusieurs AppDomain instances dans .NET Framework.
Remarque
- AssemblyLoadContext ne fournit aucune fonctionnalité de sécurité. Tout le code dispose d’autorisations complètes du processus.
- Dans .NET Core 2.0 - 2.2 uniquement, AssemblyLoadContext est une classe abstraite. Pour créer une classe concrète dans ces versions, implémentez la AssemblyLoadContext.Load(AssemblyName) méthode.
Utilisation dans le runtime
Le runtime implémente deux contextes de chargement d’assembly :
- AssemblyLoadContext.Default représente le contexte par défaut du runtime, utilisé pour l’assembly principal de l’application et ses dépendances statiques.
- La Assembly.LoadFile(String) méthode isole les assemblys qu’il charge en instanciant le plus simple AssemblyLoadContext. Il a un schéma d’isolation simpliste qui charge chaque assembly dans son propre AssemblyLoadContext sans résolution de dépendance.
Utilisation des applications
Une application peut créer sa propre AssemblyLoadContext solution personnalisée pour des scénarios avancés. La personnalisation se concentre sur la définition des mécanismes de résolution des dépendances.
Les AssemblyLoadContext deux points d’extension permettent d’implémenter la résolution d’assembly managé :
- La AssemblyLoadContext.Load(AssemblyName) méthode fournit la première chance de AssemblyLoadContext résoudre, de charger et de retourner l’assembly. Si la AssemblyLoadContext.Load(AssemblyName) méthode retourne
null
, le chargeur tente de charger l’assembly dans le AssemblyLoadContext.Default. - Si l’assembly AssemblyLoadContext.Default ne peut pas être résolu, l’original AssemblyLoadContext obtient une deuxième chance de résoudre l’assembly. Le runtime déclenche l’événement Resolving .
En outre, la méthode virtuelle autorise la AssemblyLoadContext.LoadUnmanagedDll(String) personnalisation de la résolution d’assembly non managée par défaut. L’implémentation par défaut retourne null
, ce qui entraîne l’utilisation de sa stratégie de recherche par défaut. La stratégie de recherche par défaut est suffisante pour la plupart des scénarios.
Défis techniques
Il n’est pas possible de charger plusieurs versions du runtime dans un seul processus.
Attention
Le chargement de plusieurs copies ou différentes versions d’assemblys d’infrastructure peut entraîner un comportement inattendu et difficile à diagnostiquer.
Conseil
Utilisez des limites de processus avec communication à distance ou interprocesseur pour résoudre ce problème d’isolation.
Le minutage du chargement de l’assembly peut rendre les tests et le débogage difficiles. Les assemblys sont généralement chargés sans leurs dépendances immédiatement résolues. Les dépendances sont chargées, car elles sont nécessaires :
- Quand le code se branche dans un assembly dépendant.
- Lorsque le code charge des ressources.
- Lorsque le code charge explicitement des assemblys.
L’implémentation de peut ajouter de AssemblyLoadContext.Load(AssemblyName) nouvelles dépendances qui doivent être isolées pour permettre à différentes versions d’exister. L’implémentation la plus naturelle place ces dépendances dans le contexte par défaut. Une conception minutieuse peut isoler les nouvelles dépendances.
Le même assembly est chargé plusieurs fois dans différents contextes.
- Cela peut entraîner des messages d’erreur confus, par exemple « Impossible de convertir l’objet de type « Sample.Plugin » en type « Sample.Plugin ».
- Le marshaling entre les limites d’isolement n’est pas trivial. Une solution classique consiste à utiliser une interface définie dans un assembly qui est uniquement chargé dans le contexte de chargement par défaut.