How MEF discovers Parts

Jan 15, 2010 at 10:25 PM

Hi,

I am new to MEF and I having a quick question.

Let's say I have an app with a dozen possible extension .dlls in a directory.  Now I would like to get all plug-ins that implment a certain interface.

Will MEF load all 12 dlls to search for the plug-ins or will it just examine the assembly manifests?

Thanks in advance,

Kavan

Jan 15, 2010 at 10:39 PM

Using our default catalogs it will load all assemblies to find the exports. Is that a problem?

MEF does support creating cached catalogs using our ReflectionModelServices api. Using that API you could for example invoke mono.cecil or cci to discover available exports. We don't have anything that does as of yet. You can find out more about how the API works in Mike Taulty's post on building a XAML programming model here.

Regards

Glenn 

Jan 15, 2010 at 11:06 PM

Hi Glenn,

My scenerio is as follows, I have different assemblies that contain UI components and loading the assemblies to examine the types triggers a lot of dependent assemblies to load.

The approach I tried before looking at MEF was to decorate any assembly that contains UI exports with an assembly level attribute.  I would then examine all loaded assemblies and perform appropriate cached cataloging.

I say cached catalogin because this done in a designer context (e.g. Blend or VS2010) so it is a bit time sensitive and the loading just makes it worse.  It may also be retriggered when another build occurs.

For loaded assemblies it is not an issue, however, the end-user's project may contain extra assemblies in the project output directory that are not loaded (due to no direct references), but do contain UI parts.

The solution I tried was to enumerate all assemblies in the output directory, however, using Assembly.Load or Assembly.ReflectionLoad both result in undesirable side-effects.  ReflectionLoad still fails to retrieve assembly level attributes (because more dependant attributes must be loaded).

I was just about to try mono.cecil, but my follow-on question is how hard would it be to use the cached catalogs and is post referenced above a sample of that?

Many thanks,

Kavan

Jan 15, 2010 at 11:12 PM

Hi Kavan

There's a few options here.

1. Is to have all parts put in a separate folder. You can then use DirectoryCatalog to only load those parts. You can even have a specific extension if you want and match on that as DC lets you pass in a filter.

2. You can also use AssemblyCatalogs to only load the assemblies you want to. This way you could have a list of assembly names, or have an assembly level attribute and read the metadata to find those assemblies that you want to load. Once you find the ones you want you create an assembly catalog for each and then add it to an aggregate catalog which you pass to the container.

Let me know if this makes sense

Glenn

Jan 15, 2010 at 11:36 PM

Hi Glenn,

The problem is that the assemblies are in a directory with other assemblies, and their extension may not be changed.

However, the real issue is the reading of the assembly level attribute without triggering a LoadAssembly.

But let's put that issue aside, my question now is, let's say I do know which assemblies contain the parts as you say in option 2.  Would it be possible to tell MEF the following assemblies contain the following parts and then when MEF needs the part it loads the assembly.

This would kind of be like an XML config in code where I would tell MEF assembly X contains types B, C, and D that implment interface I.

Is that possible?

Thanks again,

Kavan

Jan 15, 2010 at 11:40 PM

You could use Mono cecil or CCI to read the assemblies. Or have a list that is cached...you read the assemblies the first time, but then store the names for future reads.

Yes it is possible to do what you ask, but it takes more work. If you follow the link I sent you he is showing defining parts in XAML...and they don't load till needed I believe.

Glenn