MEF 2:导入多种 [英] MEF 2: import many

查看:130
本文介绍了MEF 2:导入多种的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我如何使用属性的分类方法来配置MEF。
我阅读下面的文章:
http://msdn.microsoft.com/en-us/magazine/jj133818.aspx
<一href="http://blogs.microsoft.co.il/blogs/bnaya/archive/2013/01/12/mef-2-0-mini-series-part-4-fluent-import.aspx" rel="nofollow">http://blogs.microsoft.co.il/blogs/bnaya/archive/2013/01/12/mef-2-0-mini-series-part-4-fluent-import.aspx

I'm use attribute-free approach to configuring MEF.
I'm read following articles:
http://msdn.microsoft.com/en-us/magazine/jj133818.aspx
http://blogs.microsoft.co.il/blogs/bnaya/archive/2013/01/12/mef-2-0-mini-series-part-4-fluent-import.aspx

测试code(控制台应用程序项目,.NET 4.5):

Test code (console application project, .NET 4.5):

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Registration;
using System.Linq;

namespace MEF2
{
    public interface IPlugin
    {
        void Run();
    }

    public interface IPluginMetadata
    {
        string Name { get; }
        string Version { get; }
    }

    [MetadataAttribute]
    [AttributeUsage(AttributeTargets.Class, AllowMultiple=false)]
    public class PluginMetadataAttribute : ExportAttribute, IPluginMetadata
    {
        public string Name { get; set; }
        public string Version { get; set; }

        public PluginMetadataAttribute(string name, string version)
            : base(typeof(IPlugin))
        {
            Name = name;
            Version = version;
        }
    }

    [PluginMetadata("Plugin1", "1.0.0.0")]
    public class Plugin1 : IPlugin
    {
        public void Run()
        {
            Console.WriteLine("Plugin1 runed");
        }
    }

    [PluginMetadata("Plugin2", "2.0.0.0")]
    public class Plugin2 : IPlugin
    {
        public void Run()
        {
            Console.WriteLine("Plugin2 runed");
        }
    }


    class Program
    {
        CompositionContainer container;
        IEnumerable<Lazy<IPlugin, IPluginMetadata>> plugins = Enumerable.Empty<Lazy<IPlugin, IPluginMetadata>>();

        static void Main(string[] args)
        {
            var program = new Program();

            foreach (var plugn in program.plugins) {
                Console.WriteLine("{0}, {1}", plugn.Metadata.Name, plugn.Metadata.Version);
                plugn.Value.Run();
            }
        }

        Program()
        {
            var builder = new RegistrationBuilder();
            builder
                .ForTypesDerivedFrom<IPlugin>()
                .Export<IPlugin>();
            builder
                .ForType<Program>()
                .Export()
                .ImportProperties<IPlugin>(
                    propertyFilter => true,
                    (propertyInfo, importBuilder) => {
                        importBuilder.AsMany();
                    }
                );

            var catalog = new AggregateCatalog(
                new AssemblyCatalog(typeof(Program).Assembly, builder)
            );

            container = new CompositionContainer(catalog);
            container.ComposeParts(this);
        }
    }
}

出口工作正常。
但是,当我尝试导入很多这是行不通的。照片 请帮我解决这个问题。

Exports works fine.
But when I try import many it doesn't work.
Please help me solve this problem.

推荐答案

这是不是一个属性的分类(必须),因为出口的做法,是因为(声明)。从 ExportAttribute 您的自定义元数据属性派生。

This is not an attribute free (imperative) approach since the export is attributed (declarative). Your custom metadata attribute derives from ExportAttribute.

有关此code工作,你需要做到以下几点:

For this code to work you need to do the following:

  • 删除从构造code势在必行出口。
  • 通过注册商向 AssemblyCatalog 。如果没有这个登记构建器不能使用。
  • 更新公约为基础的进口与延迟&LT; IPlugin,IPluginMetadata&GT; ,因为这是正在导出
  • 替换调用 ComposeParts GetExports
  • Remove the imperative export from the constructor code.
  • Pass the registration builder to the AssemblyCatalog. Without this the registration builder cannot be used.
  • Update the convention-based import with Lazy<IPlugin, IPluginMetadata> since this is what is being exported.
  • Replace the call to ComposeParts with GetExports.

更新后的构造函数code是:

The updated constructor code is:

            var builder = new RegistrationBuilder();

            builder
                .ForType<Program>()
                .Export()                
                .ImportProperties<Lazy<IPlugin, IPluginMetadata>>(
                    propertyFilter => true,
                    (propertyInfo, importBuilder) =>
                    {
                        importBuilder.AsMany();
                    }
                );

            var catalog = new AggregateCatalog(
                new AssemblyCatalog(typeof(Program).Assembly, builder)
            );

            container = new CompositionContainer(catalog);
            //container.ComposeParts(this);
            plugins = container.GetExports<IPlugin, IPluginMetadata>();

我不知道如何使这项工作与 ComposeParts 呢。我会看看它。另外,自定义元数据并没有从 ExportAttribute 导出。它可以从 System.Attribute 导出。这会让你有一个必要的出口也是如此。

I'm not sure how to make this work with ComposeParts yet. I will have a look at it. Also the custom metadata does not have to derive from ExportAttribute. It can derive from System.Attribute. This will let you have a imperative export as well.

这篇关于MEF 2:导入多种的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆