使用MEF时,Type.GetType返回null

我目前正在使用MEF来导入插件项目,因为插件是用WPF编写的,每个插件都有一个视图和一个viewmodel。 插件知道viewmodel,但主shell UI将构造视图并使用约定优于配置类型模式绑定viewmodel。

我使用了Build-your-own-MVVM-framework示例中的一些代码来执行自动视图发现:

[ImportMany(typeof(IPlugin))] public IEnumerable Plugins { get; set; } var viewTypeName = this.Plugins.First().ViewModel.GetType().AssemblyQualifiedName.Replace("Model", string.Empty); var viewType = Type.GetType(viewTypeName,true); 

目前的代码只是获取第一个插件并从名称中取出Model ,返回视图名称并获取视图类型以便我可以构造它。 那么viewType的一个例子是:

 PluginTest.TestView, PluginTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null 

但是,当我调用Type.GetType(viewType)我得到null,如果我添加true以抛出exception,我得到exception:

 Could not load file or assembly 'PluginTest, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified. 

即使已经使用MEF加载了它。

如果我做:

 var types = Assembly.GetAssembly(this.Plugins.First().ViewModel.GetType()).GetTypes(); 

我得到了插件程序集中所有类型的列表,到目前为止只有PluginTest.TestViewPluginTest.TestViewModel

任何人都可以帮我这个吗?

编辑:对不起之前没有提到,插件是在我的主shell应用程序的不同程序集。

做这样的事情可能最简单:

 var modelType = this.Plugins.First().ViewModel.GetType(); var viewTypeName = modelType.FullName.Replace("Model", string.Empty); var viewType = modelType.Assembly.GetType(viewTypeName); 

我不确定为什么Type.GetType不适合你 – 程序集解析是一个棘手的野兽 – 但如果你知道程序集应该定义类型,我肯定会通过Assembly.GetType来代替。

程序集可能已加载到Load-From上下文中,而Type.GetType()不适用于在该上下文中加载的程序集 。 MEF尝试在默认上下文中加载程序集,但如果这不起作用,则会在Load-From上下文中加载它们。

有关.NET中的程序集加载上下文的更多信息

这个问题早已得到解答,但万一有人偶然发现,这是我的解决方案。

正如其他答案所指出的那样,问题是尽管程序集已经通过MEF加载,但是一旦使用GetType() ,它就会再次加载。 不幸的是,我无法控制调用GetType()的代码,因此Jon Skeet的解决方案在我的情况下不起作用。

在我的例子中,可以通过将插件程序集的位置添加到应用程序的探测路径来解决问题。

另一种解决方案(我最终做的)是实现AssemblyResolve事件,并手动加载程序集。 这个解决方案非常灵活,与探测路径解决方案相反,如果您事先不知道插件的安装目录,它也可以工作。

另外:如果您的插件有任何依赖程序集,则必须使用这两种解决方案中的一种,否则在首次使用这些依赖项时会出现FileNotFoundexception。