2017-06-16 3 views
4

Ich verbrachte mehrere Stunden damit, herauszufinden, wie man Parameter über MEF (System.Composition) an einen Plugin-Konstruktor übergibt, aber alles ohne Erfolg. Natürlich gibt es sehr wenige relevante Dokumente und ein Blick durch den Quellcode hat nicht geholfen.Parameter an den Plugin-Konstruktor über MEF auf .NET Core übergeben?

Dies war mit der CompositionHost.ComposeExportedValue-Methode sehr einfach zu tun, aber in der .NET Core-Version kann ich nichts finden, was funktioniert. Ich habe meinen unvollständigen Code unten eingefügt, gefolgt von der Ausnahme, die ausgelöst wird.

Jede Hilfe in dieser Hinsicht würde sehr geschätzt werden. Danke ....

using System; 
using System.Composition; 
using System.Composition.Hosting; 
using System.Reflection; 

namespace MefMe 
{ 
    public interface IPlugin 
    { 
     void Alert(); 
    } 

    [Export(typeof(IPlugin))] 
    public class Plugin : IPlugin 
    { 
     private string code; 

     [ImportingConstructor] 
     public Plugin(string code) 
     { 
      this.code = code; 
     } 

     public void Alert() => Console.WriteLine(code); 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      var config = new ContainerConfiguration() 
       .WithAssembly(Assembly.GetEntryAssembly()); 

      var container = config.CreateContainer(); 

      // Throws a CompositionFailedException; see notes 
      var plugin = container.GetExport<IPlugin>(); 

      plugin.Alert(); 
     } 
    } 
} 

System.Composition.Hosting.CompositionFailedException aufgetreten
HResult = 0x80131500 Message = Kein Export für den Vertrag 'String' gefunden wurde -> durch Import 'Code' des Teils erforderlich 'Plugin' -> erforderlich von ursprünglichem Antrag auf Vertrag 'IPlugin' Source = Stacktrace: bei System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckTarget (CompositionDependency Abhängigkeit, HashSet 1 checked, Stack 1 Prüfung) bei System.Composition.Hosting. Core.ExportDescriptorRegistryUpdate.CheckDepend Ency (CompositionDependency Abhängigkeit, HashSet 1 checked, Stack 1 Kontrolle) bei System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckTarget (CompositionDependency Abhängigkeit, HashSet 1 checked, Stack 1 Kontrolle) bei System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.Execute (CompositionContract Vertrag) bei System.Composition.Hosting.Core.ExportDescriptorRegistry.TryGetSingleForExport (CompositionContract exportkey, ExportDescriptor & defaultForExport) bei System.Composition.Hosting.Core.LifetimeContext.TryGetExport (CompositionContract Vertrag, Objekt & Export) bei Syste m.Composition.CompositionContext.GetExport (CompositionContract contract) bei System.Composition.CompositionContext.GetExport [TEXPORT] (String contractName) bei MefMe.Program.Main (String [] args) in C: \ Benutzer \ Louis \ Desktop \ MefMe \ MefMe \ Program.cs: Linie 36

Antwort

2

Leider ist ComposeExportedValue derzeit nicht unterstützt. Es gibt eine offene Github Issue Anforderung der Funktion.

Es gibt eine langatmige Workaround, die den Trick machen wird. Es gibt keine Möglichkeit, dass ich Exporte mit bevölkerten Werten erstellen kann. Sie können explizite Eigenschaftsexporte mit den Werten erstellen, die im Konstruktor über einen statischen Satz von Parametern festgelegt sind. Ich habe Ihr Code-Snippet aktualisiert, um meine Lösung anzuzeigen.

namespace MefMe 
{ 
    public interface IPlugin 
    { 
     void Alert(); 
    } 

    [Export(typeof(IPlugin))] 
    public class Plugin : IPlugin 
    { 
     private string code; 

     [ImportingConstructor] 
     public Plugin([Import("code")] object code) 
     { 
      this.code = (string)code; 
     } 

     public void Alert() => Console.WriteLine(code); 
    } 

    public class Parameters 
    { 
     public static IEnumerable<Tuple<string, object>> PopulatedParameters { get; set; } 
     [Export("code", typeof(object))] 
     public object code { get; set; } 

     public Parameters() 
     { 
      foreach (var param in PopulatedParameters) 
       SetParameter(param.Item1, param.Item2); 
     } 

     void SetParameter(string nameOfParam, object value) 
     { 
      var property = typeof(Parameters).GetProperty(nameOfParam, BindingFlags.Public | BindingFlags.Instance); 
      property.SetValue(this, value); 
     } 


    } 

    public class Program 
    {   
     static void Main(string[] args) 
     { 
      Parameters.PopulatedParameters = new Tuple<string, object>[] { new Tuple<string, object>("code", "myvalue") }; 

      var config = new ContainerConfiguration() 
       .WithAssembly(typeof(IPlugin).Assembly); 
      var container = config.CreateContainer(); 

      // Throws a CompositionFailedException; see notes 
      var plugin = container.GetExport<IPlugin>(); 

     } 
    } 
} 
0

Für jetzt müssen Sie Ihren eigenen ExportDescriptorProvider erstellen. Dann fügen Sie es mit "WithProvider" in die Containerkonfiguration ein. Hier ist ein example.

(Das war fast genau die gleiche Frage.)

nicht Kredit nehmen Bedeuten für Arbeit jemand anderem; Ich denke nur, Stackoverflow kann eine Menge mehr Material im Zusammenhang mit System.Composition verwenden.

Verwandte Themen