2 votes

Vérifier à l'avance si l'assemblage peut être trouvé

Mon programme .net utilise un assemblage, qui devrait être installé dans le GAC.

Si l'assemblage est correctement installé, il sera chargé dès la première utilisation, ce qui est formidable. Si, par exemple, j'utilise un type de l'assemblage comme ceci :

ESRI::ArcGIS::esriSystem::AoInitialize^  aoi = gcnew ESRI::ArcGIS::esriSystem::AoInitializeClass();

L'assemblage sera chargé.

Il arrive parfois que l'assemblage ne soit pas présent dans le GAC, et j'ai besoin que le programme en soit conscient mais ne se plante pas.

J'ai essayé d'envelopper l'utilisation de l'assemblage dans un bloc try/catch comme ceci :

try
{
  ESRI::ArcGIS::esriSystem::AoInitialize^  aoi = gcnew  ESRI::ArcGIS::esriSystem::AoInitializeClass();
}
catch (System::Exception^ )
{
  // assembly not found
}

Mais le programme ne lèvera pas d'exception et se plantera à la place.

Comment puis-je vérifier à l'avance si l'assemblage est dans le GAC et peut être utilisé sans planter ? Ou comment puis-je détecter le crash et désactiver les éléments de menu correspondants dans mon programme ?

2voto

Hans Passant Points 475940

Vous avez un mauvais modèle mental sur la façon dont les assemblages sont chargés. Il fait no se produisent lorsque vous créez une instance d'un type dans l'assemblage. Le compilateur JIT est celui qui a besoin de l'assemblage en premier. Pour générer le code machine de la méthode. Si vous regardez la pile d'appels pour l'exception, vous verrez que l'exception a été levée dans la méthode méthode d'appel .

Du moins, c'est ce qui se passe normalement lorsque vous utilisez un jitter Microsoft, il génère le code machine à la demande, au dernier moment. C'est différent pour d'autres jitters, comme celui de Mono, qui compile avec beaucoup plus d'empressement.

Vous pourriez attraper l'exception dans la méthode appelante mais c'est assez fragile. Outre la dépendance à la gigue, vous devrez également attribuer à la méthode [MethodImpl(MethodImplOptions.NoInlining)] pour vous assurer que ce code ne sera jamais inline. En effet, le type sera à nouveau nécessaire trop tôt.

La bonne solution consiste à utiliser une architecture de plug-in. Vous devez utiliser un type d'interface pour déclarer les propriétés et les méthodes que vous souhaitez utiliser dans votre programme principal. Ce type d'interface doit être déclaré dans un assemblage séparé, référencé à la fois par votre programme principal et par le plugin. Et déployé avec votre programme principal, que l'option plugin soit disponible ou non pour votre client. Utilisez Assembly.Load() pour charger l'assemblage du plugin et Assembly.CreateInstance() pour créer l'instance concrète du type qui implémente l'interface. Et ne faites jamais référence au type concret dans votre code, seulement au type d'interface. Vous trouverez de nombreux exemples de cette méthode en effectuant une recherche sur Google.

0voto

Paulo Santos Points 8148

Le mieux serait d'ajouter tous les assemblages nécessaires au cours du processus d'installation.

Cependant, ce que vous souhaitez peut être obtenu par une simple vérification du type avant de créer le type.

Quelque chose comme ça :

var t = System.Type.GetType("TypeName, Assembly");
if (t == null) throw CannotLoadTypeException();

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X