2011-11-02 49 views
3

我有一个应用程序,它可以导出多个相同类的对象,以及只导入特定类的对象。例如C#MEF:导出一个类型的多个对象,并导入特定的对象

public class Part 
{ 
    string name; 
    public Part(string nm) 
    { 
    name = nm; 
    } 
} 

public class Car //Exports ALL Parts of the Car 
{ 
    [Export(typeof(Part))] 
    public Part steeringWheel = new Part("SteeringWheel"); 

    [Export(typeof(Part))] 
    public Part engine = new Part("Engine"); 

    [Export(typeof(Part))] 
    public Part brakes = new Part("Brakes"); 
} 

public class SystemMonitorPlugin //Imports only SOME Parts from the Car 
{ 
    [Import(typeof(Part))] 
public Part engine; 

    [Import(typeof(Part))] 
    public Part brakes; 
} 

有人可以解释我怎么能实现这种行为?

回答

4

你需要一个合同(接口)和元数据的合同(接口):

public interface ICarPart{ 
    int SomeMethodFromInterface(); 
} 

public interface ICarPartMetadata{ 
    string /*attention to this!!!*/ NameCarPart { get; } /* Only for read. */ 
} 

然后您导出部分:

[Export(typeof (ICarPart))] 
[ExportMetadata("NameCarPart","SteeringWheel")] /* is string!! */ 

public class SteeringWheel : ICarPart { 

    public int SomeMethodFromInterface(){ 
     ... //your stuff 
    } 
} 
[Export(typeof (ICarPart))] 
[ExportMetadata("NameCarPart","Engine")] /* is string!! */ 

public class Engine : ICarPart { 

    public int SomeMethodFromInterface(){ 
     //Each method have diferent behavior in each part. 
     ... //your stuff 
    } 
} 
[Export(typeof (ICarPart))] 
[ExportMetadata("NameCarPart","Brakes")] /* is string!! */ 

public class Brakes : ICarPart { 

    public int SomeMethodFromInterface(){ 
     //Each method have diferent behavior in each part. 
     ... //your stuff 
    } 
} 

然后你可以用ImportMany和懒惰导入:

[ImportMany()] 
    IEnumerable<Lazy<ICarPart, ICarPartMetadata>> carParts = null; 
    public void Importing(){ 
    ... 
    ... 

    foreach (Lazy<ICarPart,ICarPartMetadata> item in carParts){ 
     switch (item.Metadata.ICarPartMetadata.ToString()){ 
      case "SteeringWheel": 
       item.Value.SomeMethodFromInterface(); 
      break; 
      case "Engine": 
       item.Value.SomeMethodFromInterface(); 
      break; 
      case "Brakes": 
       item.Value.SomeMethodFromInterface(); 
      break; 
      default: 
      ... 
      break; 
     } 
    } 
+0

这种方法相对于Adam提出的优点是什么?这种方法是不是需要更多的开销,并且不会在一点上导入所有对象,只访问你想使用的方法(即那些定义为个案的方法)?如果我最终得到超过100个对象,这会阻碍只有1或2个插件才能使用的插件性能。 –

+0

如果您需要几次导入,您可以使用Adam方法。另一方面,当您有很多导入时,Lazy类很有用。 - >“实际上懒惰是当你的插件很重,需要大量内存时使用的”http://dailydotnettips.com/2011/09/02/getting-lazy-with-mef/ – Galled

+0

此外,你需要一个合同来确保您的解决方案将随着时间的推移而保持不变,因为通过合同您可以在不接触主项目的情况下改变您的出口类。如果你在没有合同的情况下放置这些名字将非常依赖于这些零件,你将失去一些MEF的好处。 – Galled

10

可以命名出口:

[Export("SteeringWheel", typeof(Part))] 

当你想要一个特定的一个,

[Import("Engine", typeof(Part))] 

,您仍然可以导入许多类型部分,如果你不指定名称。

+0

非常好,谢谢! –

+1

如果我的回答解决了您的问题,请务必将其标记为答案。 –

+0

@AdamBarney,找到你的答案,在SL中做同样的事,但它不起作用,你是否看到任何明显的错误? http://stackoverflow.com/questions/39758390/exporting-by-type-and-contract-importmany-does-not-work-as-expected – katit