photo_tom photo_tom - 2 months ago 23
C# Question

Lazy Loading DLL's with MEF

I'm doing my first project with MEF and am seriously unable to understand how to use lazy loading. My code is -

public static class MefLoader
{
private static CompositionContainer Container;

[ImportMany(typeof(IControlModule), AllowRecomposition = true)]
private static IEnumerable<Lazy<IControlModule, IImportComponentCapabilites>>
DllList { get; set; }

static MefLoader()
{
var catalog = new AggregateCatalog();
catalog.Catalogs.Add(new DirectoryCatalog("."));
Container = new CompositionContainer(catalog);

}


I understand most of how to use MEF, except that I don't see how to initialize the DllList object. I want to use lazy loading because in final system, we have a great many options and only about 10% are going to be used at any one time.

Answer

First, you are trying to import objects into a static property. This is not supported by MEF: MEF composes objects, not classes. If you want to initialize static properties, you have to do it manually like this:

DllList = container.GetExports<IControlModule, IImportComponentCapabilites>();

Now about lazy loading: DirectoryCatalog creates a AssemblyCatalog for each assembly in the directory. The AssemblyCatalog implementation in MEF will enumerate all types in the assembly as soon as AssemblyCatalog.Parts is called, which will happen when you pull an export from the container. This means that the assembly is loaded even before MEF has determined that it contains a part that it actually needs.

In order to truly have lazy loading of assemblies, the information about which parts are available in those assemblies would need to be cached somewhere. MEF currently does not have such a built-in cache mechanism out of the box. However, there is a ComposablePartCatalogAssemblyCache implementation in the samples included with the MEF source code at codeplex.

The only thing that Lazy<T> does is postpone the moment that the constructor of the part is called. This can already speed up things but it won't postpone the loading of assemblies.