Search code examples
c#wpfmef

Which parts of MEF should be customized for dynamic loading of plug-ins in a distributed application


My simulation application will be using plug-ins to provide the simulation algorithms and data structures for the storage of the simulation data. The application consists of two parts. First is the host application which provides the UI (either as WPF UI or as plug-in to a CAD application). This application handles all interaction with the user but does not perform any of the simulation calculations, neither does it store any of the simulation data. The second part is the data application which performs the simulation calculations. The data application does not have any way for the user to interact with it directly, all input is provided via a connection with the host (either via named pipe if both are on the same machine or via TCP if they are on different machines). This approach allows distributed computing via a single host with multiple data applications.

The data application is provided with the data storage methods, simulation algorithms etc. via one or more plug-ins so that it is easy to add new capabilities. In order for this to work the plan is to:

  • Let the host application perform the search for plug-ins. The host should store data describing the plug-ins and their meta-data, but it will never instantiate any of the plug-in classes. In order to prevent loading the assemblies into the host application it will be necessary to store the descriptions of the plug-ins in some kind of serialized format.
  • The dataset application will request plug-in information from the host, determine the desired plug-ins to load, request transfer of the correct assemblies (necessary for distributed computing) and load the plug-ins.
  • Selection of the correct plug-ins should be based on Type (as in System.Type) and additional information, like priority etc.

For all of this to work I think I will have to:

  • Write some kind of delay loading catalog for the data application (something like DeploymentCatalog in Silverlight). The trick will probably be to only request the assembly to be transferred and loaded after the application figures out which classes need to be instantiated.
  • Write my own assembly scanning mechanism for the host application that stores the plug-in information in some serialized (string?) format to prevent the plug-in assemblies from being loaded into the host application.
  • Write some kind of loading mechanism that can select the correct plug-in class and determine how to load it and which construction arguments to provide.
  • Find some way to allow plug-ins to specify setting values (including default values and localized descriptions of said values) and meta-data.

I would like to do as little work as possible and so I had a look at some of the available plug-in systems for .NET. From the looks of it MEF seems to be the most promising candidate. I have read up on the architecture and abilities of MEF but I am still a bit in the dark as to where I should be focussing my energy. So my question is which parts of MEF will have to be customized in order to make MEF work with my planned approach?


Solution

  • It turns out that MEF is missing certain bits that are required for the delay loading of plug-in assemblies, however it is possible to use some parts of MEF in the plug-in part of the application.

    • Delay loading of the components is done by implementing a handler for the AppDomain.AssemblyResolve event. This resolver uses the existing communication capabilities (which are necessary to communicate between the host application and the dataset application) to transfer the desired assemblies.
    • Scanning and serialization of plugin data is implemented as explained in the answer to the relevant question. This part heavily uses MEF to do the detection and serialization of the plug-in data.
    • Composing the parts without instantiating the objects seems to not be possible in MEF so this section of the application is implemented as as per the implementation provided by this answer