C#MEF:Threadsafe导出

时间:2011-11-08 20:53:36

标签: c# mef

假设我有一个CarSystem类,其中包含CarParts个对象的集合。现在我想为系统编写一个立体声插件,我希望所有插件的格式为:

public interface ICarPluginMetaData
{
  string Name {get;}
  string Description {get;}
  int Status {get; set;}
}

public interface ICarPlugin
{
  void int setStatus(int newStatus);
}

[Export(typeof(ICarPlugin))]
[ExportMetaData("Name", "Stereo")]
[ExportMetaData("Description","Plays music")]
[ExportMetaData("Status", 0)]
public class StereoPlugin : ICarPlugin
{
  [ICarPluginImport("FrontSpeakers")]
  public CarPart myFrontSpeakersPointer;

  [ICarPluginImport("RearSpeakers")]
  public CarPart myRearSpeakersPointer;

  [ICarPluginImport("subwoofer")]
  public CarPart mysubwooferPointer;

  [Export]
  public void setStatus(int newStatus)
  {
    Status = newStatus;
  }
}

现在在我的CarSystem类中,我定义了导出,但默认行为是创建1个静态对象,并将其交给所有导入它的人;我怎么能做到以下几点:

[ExportAsThreadsafe]
public CarPart FrontSpeakers

[ExportAsThreadsafe]
public CarPart RearSpeakers

[ExportAsThreadsafe]
public CarPart Subwoofer

[ExportAsThreadsafe]
public CarPart DashLights

这样当我创建第二个插件,在一个单独的线程上运行时,我得到一个与所有插件的实际对象的线程安全连接?

2 个答案:

答案 0 :(得分:1)

在MEF中提供线程安全性的一种方法是在每个线程中执行单独的独立MEF组合。在该组合中构造的所有内容然后是该线程的本地。任何跨线程访问都在您的控制之下,您可以使用正常的线程安全技术。

我不清楚你是否要加载多个立体声插件并让它们可用于/绑定到一个全局CarSystem,或者你只是在谈论在不同的线程中拥有多个CarSystems,彼此独立。你可以通过MEF用一个线程中的特定立体声插件组成CarSystem来完成后者。

答案 1 :(得分:0)

这是我最终做的事情(伪代码):

Foreach plugin dynamically loaded
{
    //Via reflection
    Foreach field in the plugin
    {
        See if the field has an attribute attached
        Find the field who's name is the same as it's attribute's name
        {
            Using some lookup method, find the object in the CarSystem
            collection who's name is the same as the attribute name.
            create a concurrencyQueue using proxy object
            call field.SetValue(pluginObject, new Proxy Object) //Reflection call
        }
    }
}

Foreach plugin dynamically loaded { //Via reflection Foreach field in the plugin { See if the field has an attribute attached Find the field who's name is the same as it's attribute's name { Using some lookup method, find the object in the CarSystem collection who's name is the same as the attribute name. create a concurrencyQueue using proxy object call field.SetValue(pluginObject, new Proxy Object) //Reflection call } } }

我基本上说过,"螺旋式MEF自动执行此操作"并使用Reflection和自定义属性自己完成。我使用MEF进行单向消息传递,但对于需要更改CarSystem中对象的插件,我使用了我的自定义" MEF"风格。