MEF 2 GetExports()失败,出现奇怪的错误

本文关键字:错误 GetExports 失败 MEF | 更新日期: 2023-09-27 18:06:53

using System;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.ReflectionModel;
using System.ComponentModel.Composition.Registration;
using System.Linq;
using System.Reflection;
namespace MefTest
{
    public interface ITest {}
    public class TestObj : ITest {}
    class Program
    {
        static void Main(string[] args)
        {
            RegistrationBuilder rb = new RegistrationBuilder();
            //Register the class
            rb.ForType<TestObj>().Export();
            var container = new CompositionContainer(new AssemblyCatalog(Assembly.GetExecutingAssembly(), rb));
            //get the type of the first part (there is only 1), which is TestObj
            Type t = ReflectionModelServices.GetPartType(container.Catalog.Parts.First()).Value;
            Type t2 = typeof(TestObj);
            if (t.Equals(t2)) //They look the same in the debugger??
            {
                //This works
                var test1 = container.GetExports(t2, null, null).FirstOrDefault().Value;
                //Fails with ArgumentException: MethodInfo must be a runtime MethodInfo object.
                var test2 = container.GetExports(t, null, null).First().Value;
            }
        }
    }
}
我创建了上面的示例来演示我遇到的问题。我硬编码类型工作的_container.GetExports(t2…)。但是当我从_container。catalog中查找类型时。当执行linq查询时,它失败了,并显示一条神秘的错误消息。

谁能给我提示一下,我哪里做错了?

编辑:简化测试用例

编辑:我发现了问题,t和t2不完全相同。t2是一个系统。RuntimeType和t是System.Reflection.Context.Custom.CustomType

我还没有解决办法,还需要进一步研究。

MEF 2 GetExports()失败,出现奇怪的错误

我解决了我自己的问题:

所以在。net 4.5中有一个叫做CustomReflectionContext的新特性,Ian Griffiths在这里解释道:。net 4.5 CustomReflectionContext:它有什么用?

简而言之,RegistrationBuilder是一个CustomReflectionContext,所以MEF使用的类型是"虚拟的"类型(System.Reflection.Context.Custom.CustomType),而不是在程序集中实际定义的类型(System.RuntimeType)。当涉及到对象的实例化时,这会导致一个问题。

解决方案是使用Type对象的UnderlyingSystemType属性。从存在于ReflectionContext中的类型指向在程序集中定义的真实类型。

所以我上面的代码看起来像这样才能正常工作:
var test2 = container.GetExports(t.UnderlyingSystemType, null, null).First().Value;