Type.GetType возвращает ноль при использовании MEF - PullRequest
3 голосов
/ 29 июня 2010

В настоящее время я использую MEF для проекта по импорту плагинов, так как плагины написаны на WPF, каждый из которых имеет представление и модель представления.Плагины знают о модели представления, но основной пользовательский интерфейс оболочки создаст представление и свяжет модель представления, используя соглашение по шаблону типа конфигурации.

Я использовал некоторый код из примера Build-your-own-MVVM-frameworkчтобы сделать автоматическое обнаружение вида:

    [ImportMany(typeof(IPlugin))]
    public IEnumerable<IPlugin> 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), я получаю ноль, если я добавляю true, чтобы вызвать исключение, я получаю исключение:

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.TestView и PluginTest.TestViewModel

Кто-нибудь может мне помочь с этим?

РЕДАКТИРОВАТЬ: Извините, не упомянул ранее, плагины находятся в разных сборкахк моему основному приложению оболочки.

Ответы [ 3 ]

4 голосов
/ 29 июня 2010

Вероятно, проще всего сделать что-то вроде этого:

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.

1 голос
/ 29 июня 2010

Сборка, вероятно, была загружена в контексте Load-From, а Type.GetType () не работает со сборками, загруженными в этом контексте .MEF пытается загрузить сборки в контексте по умолчанию, но если это не работает, он загружает их в контексте загрузки.

Подробнее о контекстах загрузки сборки в .NET

0 голосов
/ 28 июля 2015

На этот вопрос уже давно дан ответ, но на тот случай, если кто-то наткнется на это, вот мое решение.

Как уже отмечалось в других ответах, проблема в том, что хотя сборка была загружена через MEFон загружается снова, когда вы используете GetType().К сожалению, я не мог контролировать код, вызывающий GetType(), поэтому решение Джона Скита в моем случае не сработало бы.

В моем случае проблему можно было бы решить, добавив расположение сборки плагина в пробный путь приложения.

Альтернативное решение (что я в итоге и сделал) - реализовать событие AssemblyResolve и загрузить сборку вручную.Это решение очень гибкое, в отличие от решения для поиска пути, оно также работает, если вы заранее не знаете каталог установки плагина.

Также: если ваш плагин имеет какие-либо зависимые сборки, вы должны использоватьодно из этих двух решений, иначе вы получите исключение FileNotFound при первом использовании этих зависимостей.

...