2009-05-13 4 views
5

J'ai une application MEF (Microsoft Extension Framework) qui charge certains assemblages à partir d'un dossier. J'ai besoin d'énumérer les assemblages qui ont produit des exportations pour mon application.Comment énumérer des assemblys dans AggregateCatalog ou DirectoryCatalog dans MEF?

Une façon de le faire est d'énumérer les importations appelant GetExportedObject().GetType().Assembly. Mais il serait plus propre de le faire sans instanciation des importations. Existe-t-il un moyen d'obtenir des assemblys chargés à partir d'un catalogue ou d'autre chose?

J'ai besoin d'assemblys pour obtenir leurs attributs tels que copyright, version, nom et autres. Mon dossier peut contenir à la fois des assemblys avec des exports et ceux qui ne le sont pas, mais je n'ai besoin que d'assemblys qui satisfassent les imports dans l'application.

Répondre

2

Le fichier AssemblyCatalog a une propriété Assembly. AggregateCatalog ne dispose pas d'un moyen d'obtenir ces informations directement - il n'y a aucune garantie que les catalogues internes chargent même leurs pièces d'un assemblage. DirectoryCatalog n'a pas cette capacité bien qu'il puisse être possible de l'ajouter s'il y avait une bonne raison.

Pourquoi voulez-vous obtenir la liste des assemblages? Il vaut peut-être mieux ne pas utiliser un répertoire catalag, mais simplement scanner et charger vous-même les assemblages dans un répertoire, et créer un AssemblyCatalog pour chacun d'entre eux et l'ajouter à un AggregateCatalog.

EDIT: MEF n'a pas le moyen d'obtenir une liste de toutes les exportations qui ont été "utilisées" dans la composition. Vous pourriez probablement écrire votre propre catalogue qui retournerait des définitions de pièces qui étaient des shells autour des définitions de pièces par défaut et garderait une trace des pièces auxquelles GetExportedObject était appelé. Vous pouvez utiliser les API dans ReflectionModelServices pour déterminer le type correspondant à une définition de pièce donnée à partir des catalogues par défaut. Notez que l'écriture d'un tel catalogue ne serait probablement pas une entreprise simple.

+0

J'ai mis à jour la question sur pourquoi j'ai besoin des assemblages. En fait, même avoir DirectoryCatalog retourner les assemblées ne résoudrait pas mon objectif car la liste pourrait contenir des dll MEF qui n'ont rien à voir avec _my_ imports. Si je pouvais obtenir l'assembly à partir d'Export sans appeler GetExportedObject, ou avoir les assemblages satisfaits d'importations d'une autre manière ... –

+0

J'ajouterai que j'ai besoin de ce même genre de fonctionnalité.J'intègre un autre système qui utilise BuildManager et je veux ajouter des assemblages que j'utilise avec MEF à BuildManager. –

2

Voici ma solution actuelle qui fonctionne bien:

  1. Ne pas utiliser DirectoryCatalog, ensembles de charge directement et créer un AssemblyCatalog d'eux.
  2. Utilisez AssemblyCatalog.Parts pour déterminer quels assemblys ont des exports, laissez l'utilisateur les autoriser.
  3. Ajoutez uniquement les composants AssemblyCatalog autorisés à AggregateCatalog dans la composition.
0

Si vous avez accès à la source de ces assemblages, alors j'ai une solution alternative pour ajouter des assemblages un par un. Vous pouvez créer une interface appelée IModule et en faire une exigence pour tous vos assemblys pour l'exporter. Ensuite, vous pouvez les ImportAll dans votre bootstraper:

[ImportMany] 
public List<IModule> Modules { get; set; } 

Cette liste contiendra une liste de toutes les classes du module grâce auquel vous pouvez accéder à l'ensemble:

var module1 = Logic.Instance.Modules[0]; 
var fullename = module1.GetType().Assembly.FullName; 
5

C'est une façon de le faire, et est utilisé dans Caliburn.Micro:

var aggregateCatalog = new AggregateCatalog(...); 
var assemblies = aggregateCatalog.Parts 
    .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly) 
    .Distinct() 
    .ToList(); 
+0

meilleure réponse! de cette façon, je peux continuer à utiliser un DirectoryCatalog et toujours obtenir une liste de tous les assemblys qui ont été chargés (les pièces) via MEF. Dans le code ci-dessus j'ai changé AggregateCatalog en DirectoryCatalog. – juFo

+0

Merci! Cela m'a sauvé beaucoup de conflits. Je savais qu'il devait y avoir un moyen d'obtenir plus d'informations à partir de cette pauvre liste 'Parts'. –