假设我有一个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
这样当我创建第二个插件,在一个单独的线程上运行时,我得到一个与所有插件的实际对象的线程安全连接?
答案 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"风格。