2010-11-28 6 views
1

Hallo Ich habe einige Probleme in Beispiel Import-Szenarien:MEF Import Szenario

[Export(typeof(IICon))] 
public class WriteInputData : IICon 
{ 
    [Import(typeof(IIOWriter))] 
    public IIOWriter IOWriter { get; set; } 

    public object Input { get; set; } 

    public void Process() 
    { 
     IOWriter.Write(Input); 
    } 
} 

Dann hawe i zwei Klassen, die Schnittstelle implementieren IIOWriter mag:

[Export(typeof(IIOWriter))] 
public class FileWriter : IIOWriter 
{ 
    public string FilePath { get; set; } 

    public void Write(object data) 
    { 
     if (string.IsNullOrEmpty(FilePath)) 
      FilePath = @"c:\test.txt"; 
     var fl = new StreamWriter(FilePath, true); 
     fl.Write((string)data); 
     fl.Flush(); 
     fl.Close(); 
    } 

    public string Name 
    { 
     get { return "FileWriter"; } 
    } 
} 
[Export(typeof(IIOWriter))] 
public class ConsoleWrite : IIOWriter 
{ 
    public void Write(object data) 
    { 
     Console.WriteLine((string)data); 
    } 

    public string Name 
    { 
     get { return "ConsoleWrite"; } 
    } 
} 

Wie kann ich das so an Benutzer lassen er kann das in der Laufzeit ändern, also Beispiel, wenn er Typ in ListBox FileWriter auswählt, als der IIOWriter in WriteInputData wird injiziert FileWriter Ende so ein .. Sorry für mein schlechtes Englisch.

Antwort

2

Sie wahrscheinlich einige Metadaten für den Export liefern müssen, so wie:

[Export(typeof(IIOWriter)), 
ExportMetadata("Name", "ConsoleWriter")] 
public class ConsoleWriter : IIOWriter 
{ 

} 

Der Grund, warum Sie dies tun müssen, ist, dass Sie vor der Zeit wissen müssen, was die Benutzerauswahl übereinstimmt. Aus diesem Grund, können Sie Ihr Design, Refactoring, die Abhängigkeit von der IOWriter Eigenschaft zu entfernen:

[Export(typeof(IICon))] 
public class WriteInputData : IICon 
{ 
    public object Input { get; set; } 

    public void Process(IIOWriter writer) 
    { 

    } 
} 

Wenn Sie Ihre Process Methode definieren, die in einer Instanz zu nehmen, können wir lösen sie die CompositionContainer verwenden. Zum einen eine Metadaten-Schnittstelle definieren, die Ihren ExportMetadata Wert entspricht:

public interface INamedMetadata 
{ 
    string Name { get; } 
} 

Und dann können wir die Instanz beheben:

public IIOWriter GetWriter(string name) 
{ 
    return container 
    .GetExports<IIOWriter, INamedMetadata>() 
    .Where(e => e.Metadata.Name.Equals(name, StringComparison.OrdinalIgnoreCase)) 
    .Select(e => e.Value) 
    .FirstOrDefault(); 
} 

Hoffnung, die Sie in die richtige Richtung zeigt ....

+2

+1, aber es ist nicht erforderlich, den Container explizit aufzurufen, um Metadaten zu verwenden. Sie können einfach 'IEnumerable > 'importieren. –