2011-08-26 20 views
5

के साथ मैं अपने प्रोजेक्ट के लिए एमईएफ को डीआई के रूप में उपयोग करना चाहता हूं। मेरे पास 1 प्रोजेक्ट है और प्रत्येक कक्षा जो रचना की जानी चाहिए वहां मौजूद है (वे एक इंटरफ़ेस साझा करते हैं)। अब मैं मेटाडेटा मान निर्दिष्ट करके उनमें से एक बनाना चाहता हूं। यहाँ परिभाषाओं है:MEF GetExportedValue मेटाडेटा

public interface IGatewayResponseReader 
{ 
    object Read(string msg); 
} 

[Export(typeof(IGatewayResponseReader))] 
[ExportMetadata(G3Reader.META_KEY, "value1")] 
public class TestReader1 : IGatewayResponseReader 
{ 
    ... 
} 

[Export(typeof(IGatewayResponseReader))] 
[ExportMetadata(G3Reader.META_KEY, "value2")] 
public class TestReader2 : IGatewayResponseReader 
{ 
    ... 
} 

अब मैं MEF के माध्यम से TestReader1 का एक उदाहरण बनाना चाहते हैं, लेकिन मैं CompositionContainer के माध्यम से मेटाडाटा के आधार पर फ़िल्टर करने के लिए कैसे पता नहीं है। मुझे कुछ

Container.GetExportedValue<IGatewayResponseReader>(); 

लेकिन क्लास उदाहरण बनाने के लिए मेटाडेटा निर्दिष्ट करने के लिए कुछ चाहिए।

आपकी सहायता की बहुत सराहना की जाती है।

धन्यवाद।

उत्तर

6

जवाब @Dmitry Ornatsky द्वारा provied सही है, लेकिन निर्यात मेटाडाटा प्रदान करने के लिए पसंदीदा तरीका एक कस्टम निर्यात विशेषता का उपयोग दृढ़ता से टाइप मेटाडाटा उपयोग करने के लिए है: देखने के लिए

public interface IGatewayResponseReaderMetadata 
{ 
    string Key { get; } 
} 

[MetadataAttribute] 
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Property)] 
public class GatewayResponseReaderExportAttribute : ExportAttribute 
{ 
    public GatewayResponseReaderExportAttribute(string key) 
     : base(typeof(IGatewayResponseReader)) 
    { 
     this.Key = key; 
    } 

    public string Key { get; set; } 
} 

[GatewayResponseReaderExport("value1")] 
public class TestReader1 : IGatewayResponseReader 
{ 
} 

कोड एक आयात फिर टाइप-सुरक्षित बनाया जा सकता है। ध्यान दें कि यह करता है, तो आयात Value संपत्ति एक्सेस करने से पहले रिक्त नहीं है की जाँच करने के एक अच्छा विचार है:

class Program 
{ 
    [ImportMany] 
    private List<Lazy<IGatewayResponseReader, IGatewayResponseReaderMetadata>> _readers; 

    static void Main(string[] args) 
    { 
     CompositionContainer container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly())); 

     Program program = new Program(); 
     container.SatisfyImportsOnce(program); 


     var reader = program._readers.FirstOrDefault(r => r.Metadata.Key == "value1"); 
     if (reader != null) 
      reader.Value.Read(...); 
    } 
} 
+0

धन्यवाद फिल, मैं तुम्हारी मदद की :) सराहना करते हैं। अरे, मैंने इस तरह से कोशिश की और काम नहीं किया क्योंकि मुझे मेटाडाटाएट्रिब्यूट के बारे में पता नहीं था :(मैंने इसे समझने की कोशिश में 5 घंटे बिताए। धन्यवाद – Davita

4
class Program 
{ 
    [ImportMany] 
    private List<Lazy<IGatewayResponseReader, IDictionary<string, object>>> _readers; 

    static void Main(string[] args) 
    { 
     CompositionContainer container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly())); 

     Program program = new Program(); 
     container.SatisfyImportsOnce(program); 
     var result = program._readers.Where(r =>    
      r.Metadata.ContainsKey(G3Reader.META_KEY) && (string)r.Metadata[G3Reader.META_KEY] == "value1") 
      .First().Value; 
    } 
} 
संबंधित मुद्दे