2017-06-16 72 views
4

我花了幾個小時試圖弄清楚如何通過MEF(System.Composition)將參數傳遞給插件構造函數,但都無濟於事。毋庸置疑,有相關的文檔很少,通過源代碼看起來沒有幫助。通過.NET核心上的MEF將參數傳遞給插件構造函數?

使用CompositionHost.ComposeExportedValue方法很容易實現,但在.NET Core版本中,我似乎無法找到任何可行的方法。我在下面附上了我的不完整的代碼,然後是拋出的異常。

在這方面的任何幫助將不勝感激。謝謝....

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發生
的HResult = 0x80131500消息=沒有出口被發現的合同 '字符串' - >通過部分進口 '代碼' 要求在 System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckTarget(CompositionDependency 依賴性,HashSet的1 checked, Stack 1檢查)在 System.Composition.Hosting: - '插件'>通過對合同初始請求 'IPlugin' 源=棧跟蹤所需 。 Core.ExportDescriptorRegistryUpdate.CheckDepend ency(CompositionDependency 依賴性,HashSet的1 checked, Stack 1檢查)在 System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckTarget(CompositionDependency 依賴性,HashSet的1 checked, Stack 1檢查)在 System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.Execute(CompositionContract 合同)在 System.Composition.Hosting.Core.ExportDescriptorRegistry.TryGetSingleForExport(CompositionContract exportKey,ExportDescriptor & defaultForExport)在 System.Composition.Hosting.Core.LifetimeContext.TryGetExport(CompositionContract 合同,對象&出口)在 SYSTE m.Composition.CompositionContext.GetExport(CompositionContract 合同)在 System.Composition.CompositionContext.GetExport [TExport](字符串 contractName)在MefMe.Program.Main(字串[] args)在 C:\用戶\路易\ Desktop \ MefMe \ MefMe \ Program.cs:line 36

回答

2

不幸的是ComposeExportedValue目前不支持。有一個請求該功能的開放Github Issue

有一個冗長的解決方法,可以解決問題。我無法找到使用填充值快速創建導出的方法。你可以做的是通過靜態包參數在構造函數中設置值來創建顯式屬性導出。我已更新您的代碼片段以顯示我的解決方案。

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

現在您需要構建您自己的ExportDescriptorProvider。然後使用「WithProvider」將其添加到容器配置中。這是一個example

(這是一個幾乎一模一樣的問題。)

不要吝嗇採取信貸別人的作品;我只是認爲stackoverflow可以使用很多與System.Composition相關的材料。

相關問題