通过.NET Core上的MEF将参数传递给插件构造函数?

时间:2017-06-16 18:55:56

标签: c# asp.net-core .net-core mef

我花了几个小时试图弄清楚如何通过MEF(System.Composition)将参数传递给插件构造函数,但都无济于事。毋庸置疑,相关文档很少,通过源代码查看也无济于事。

以前很容易使用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消息=未找到合同的导出   'String' - &gt;部分'插件'的导入'代码'要求 - &gt;需要   通过合同'IPlugin'的初始请求来源= StackTrace:at   System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckTarget(CompositionDependency   依赖,HashSet 1 checked, Stack 1检查)at   System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckDependency(CompositionDependency   依赖,HashSet 1 checked, Stack 1检查)at   System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.CheckTarget(CompositionDependency   依赖,HashSet 1 checked, Stack 1检查)at   System.Composition.Hosting.Core.ExportDescriptorRegistryUpdate.Execute(CompositionContract   合同)   System.Composition.Hosting.Core.ExportDescriptorRegistry.TryGetSingleForExport(CompositionContract   exportKey,ExportDescriptor&amp; defaultForExport)at   System.Composition.Hosting.Core.LifetimeContext.TryGetExport(CompositionContract   合同,对象&amp;出口)   System.Composition.CompositionContext.GetExport(CompositionContract   合同)   System.Composition.CompositionContext.GetExport [TExport](字符串   contractName)在MefMe.Program.Main(String [] args)中   C:\ Users \ louis \ Desktop \ MefMe \ MefMe \ Program.cs:第36行

2 个答案:

答案 0 :(得分: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>();

        }
    }
}

答案 1 :(得分:0)

现在您需要构建自己的ExportDescriptorProvider。然后使用&#34; WithProvider&#34;将其添加到容器配置中。这是一个example

(那是一个几乎完全相同的问题。)

不要因为其他人的工作而受到赞扬;我只是认为stackoverflow可以使用更多与System.Composition相关的材料。