MEF Execute Plugin Exports in Threads I am developing a service application that would implement a peer to peer messaging system. I am wondering if my following code is the best approach. It works, but I am naive and it would be nice to have validation from experts for performance and reliability.

There would be about 5 plugins and a large number of messages (over 100,000 in a day. Each message could be upto 1000 characters) may be generated by each plugin and communicated to each other based on some logic.

The following are the MEFContracts -

namespace MEFContracts{

//peer to peer message transmissions.  Any plugin or core can transmit messages to one another
public interface IPeerMessage
{
void ReceiveMessage(string message,string from,string to);
}

//Core application starts a thread on the following exported plugin function
public interface IExecuteThread
{
void ExecuteThread();
}
}


The following is the Core application export -

namespace MEFCore{
[Export(typeof(IPeerMessage))]
[ExportMetadata("MEFName", "Core")]

class MEFExports:IPeerMessage
{

public void ReceiveMessage(string message, string from, string to)
{
    log.Info("Message Received by Core :" + message + from + to);
}
}
}


The following is each plugin code.

namespace MEFPlugin{
[Export(typeof(IPeerMessage))]
[ExportMetadata("MEFName", "PlugIn")]
[Export(typeof(IExecuteThread))]

public class MEFPluginExports : IPeerMessage, IExecuteThread
{
[ImportMany]
public System.Lazy&lt;IPeerMessage,
IDictionary&lt;string, object&gt;&gt;[] _peerMessageComponents
{ get; set; }

public void ReceiveMessage(string message, string from, string to)
{
    log.Info("Message Received by Plugin:" + message + " " + from + " " + to);
}

public void ExecuteThread()
{
//The core application starts this thread which generates messages.  It then transmits these messages to the various parts based on the MEFName attribute 
while(true) //I will implement later a way for the core to stop the thread when the service is stopped
{
   //generate message
   //Determine the part to communicate to, say _core

    _core.ReceiveMessage("Hello Core", "PlugIn", "Core");

}
}


And the following is the main core service

[ImportMany]
public System.Lazy&lt;IPeerMessage,
IDictionary&lt;string, object&gt;&gt;[] _peerMessageComponents
{ get; set; }
[ImportMany(typeof(IExecuteThread))]
public IEnumerable&lt;IExecuteThread&gt; _pluginThreads { get; set; }


public void Process()
{
    log.Info("MEFCoreService started");
    AssembleMEFComponents();

     foreach(IExecuteThread _pluginThread in _pluginThreads)
    {
        Thread _thread = new Thread(_pluginThread.ExecuteThread));
        _thread.Start();
        _thread.Join();

    }

}

public void AssembleMEFComponents()
{
    try
    {
        //Creating an instance of aggregate catalog. It aggregates other catalogs
        var aggregateCatalog = new AggregateCatalog();

        //Build the directory path where the parts will be available
       //using the directory catalog
        var directoryCatalog = new DirectoryCatalog(directoryPath, "*.dll");

        //Load parts from the current assembly 
        var asmCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());

        //Add to the aggregate catalog
        aggregateCatalog.Catalogs.Add(directoryCatalog);
        aggregateCatalog.Catalogs.Add(asmCatalog);

        //Crete the composition container
        var container = new CompositionContainer(aggregateCatalog);

        // Composable parts are created here 
        container.ComposeParts(this);
    }
    catch (Exception ex)
    {
        throw ex;
    }
}
}
Only a quick shot at AssembleMEFComponents() method  


declare your variables as near to their usage as possible.
using try..catch like you do is not only superfluous but also breaks the stacktrace.  
comments like //Add to the aggregate catalog are superfluous too. Comments should describe why something is done in the way it is done. What is done should be described by the code itself by using meaningful and descriptive name for methods, variables and classes.  


That being said your method should look like so  

public void AssembleMEFComponents()
{

    var directoryCatalog = new DirectoryCatalog(directoryPath, "*.dll");

    var assemblyCatalog = new AssemblyCatalog(Assembly.GetExecutingAssembly());

    var aggregateCatalog = new AggregateCatalog();
    aggregateCatalog.Catalogs.Add(directoryCatalog);
    aggregateCatalog.Catalogs.Add(assemblyCatalog );

    var container = new CompositionContainer(aggregateCatalog);

    container.ComposeParts(this);
}