Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enumerate assemblies within AggregateCatalog or DirectoryCatalog in MEF?

Tags:

c#

mef

I have a MEF (Microsoft Extension Framework) application which loads some assemblies from a folder. I need to enumerate the assemblies that produced any exports for my application.

One way to do it is to enumerate imports calling GetExportedObject().GetType().Assembly. But it would be cleaner to do this without instantiation of imports. Is there a way to get loaded assemblies from a catalog or anything else?

I need assemblies to get their attributes like copyright, version, name and such. My folder can contain both assemblies with exports and without ones, but I need only assemblies that satisfied any imports in the app.

like image 788
Sergey Aldoukhov Avatar asked May 13 '09 17:05

Sergey Aldoukhov


3 Answers

This is one way of doing it, and is used in Caliburn.Micro:

var aggregateCatalog = new AggregateCatalog(...);
var assemblies = aggregateCatalog.Parts
    .Select(part => ReflectionModelServices.GetPartType(part).Value.Assembly)
    .Distinct()
    .ToList();
like image 139
lukebuehler Avatar answered Nov 16 '22 02:11

lukebuehler


The AssemblyCatalog has an Assembly property. The AggregateCatalog does not have a way to get this information directly- there's no guarantee that the inner catalogs even load their parts from an assembly. The DirectoryCatalog doesn't have this capability although it might be possible to add it if there was a good reason.

Why do you want to get the list of assemblies? You may be better off not using a directory catalag, instead just scan and load the assemblies in a directory yourself, and create an AssemblyCatalog for each one and add it to an AggregateCatalog.

EDIT: MEF doesn't have a way of getting a list of all the exports that were "used" in composition. You could probably write your own catalog which would return part definitions that were shells around the default part definitions and kept track of which parts had GetExportedObject called on them. You can use the APIs in ReflectionModelServices to figure out which type corresponds to a given part definition from the default catalogs. Note that writing such a catalog would probably not be a simple undertaking.

like image 26
Daniel Plaisted Avatar answered Nov 16 '22 02:11

Daniel Plaisted


Here is my current solution that works nicely:

  1. Do not use DirectoryCatalog, load assemblies directly and create an AssemblyCatalog from them.
  2. Use AssemblyCatalog.Parts to find out which assemblies have exports, let the user authorize them.
  3. Add only authorized AssemblyCatalog's to the AggregateCatalog, which is ised in the composition.
like image 2
Sergey Aldoukhov Avatar answered Nov 16 '22 02:11

Sergey Aldoukhov