2017-06-16 149 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相关的材料。

相关问题