Загрузить сборку в приложение

Я пытаюсь внедрить приложение-плагин в свое приложение MVC, мне удалось разобраться с механизмами просмотра и внедрить новый контроллер из сборки в приложение с использованием MEf.

Однако сборка, которую я пытаюсь загрузить, также имеет модуль строгого типа, который я хотел бы внедрить в приложение плагина. Я загружаю сборку следующим образом:

введите здесь описание изображения

Я могу сказать, что сборка загружена в текущий домен приложения, но все же я получаю следующую ошибку:

Описание ошибки компиляции: Произошла ошибка во время компиляции ресурса, необходимого для обслуживания этого запроса. Ознакомьтесь со следующими конкретными сведениями об ошибке и соответствующим образом измените исходный код.

Сообщение об ошибке компилятора: CS0246: не удалось найти тип или имя пространства имен «автомобили» (вам не хватает директивы использования или ссылки на сборку?)

Я был бы очень признателен, если бы вы любезно дали мне какую-то подсказку.

Спасибо большое.


person cyrus-d    schedule 17.11.2013    source источник
comment
В какой ситуации вы получаете указанную ошибку?   -  person Konrad Kokosa    schedule 17.11.2013
comment
Я получаю эту ошибку при вызове представления с контроллером, который был загружен с помощью MEF из той же сборки, которую я загрузил при запуске приложения. в основном эта сборка содержит как контроллер, так и строго типизированный модуль. я загружаю контроллер с помощью MEF и MefControllerFactory. и он отлично работает, поэтому контроллер был распознан приложением MVC. но он не может найти строго типизированную сборку. надеюсь, это имеет смысл. Спасибо   -  person cyrus-d    schedule 17.11.2013
comment
Вы уверены, что путь правильный? Пути без идентификатора диска рассматриваются как относительные, поэтому может случиться так, что относительный путь окажется не там, где вы ожидаете.   -  person Pharap    schedule 17.11.2013
comment
спасибо за комментарии, да, путь актуален, потому что я вижу, что сборка загружена в домен приложения. просто упомянем, что сборка находится вне папки bin.   -  person cyrus-d    schedule 17.11.2013
comment
Попробуйте использовать a.GetExportedTypes() вместо a.GetTypes().   -  person Pharap    schedule 17.11.2013
comment
Было бы полезно получить более подробную информацию о самом исключении (например, имя и трассировка стека)   -  person Pharap    schedule 17.11.2013
comment
Большое спасибо за повтор, я пробовал GetExportedTypes, но это не сработало);   -  person cyrus-d    schedule 17.11.2013
comment
Тот факт, что это ошибка компилятора, а не ошибка времени выполнения, подсказывает мне, что вы пытаетесь использовать автомобили пространства имен где-то в своей программе, не имея пространства имен, определенного какими-либо dll, на которые ссылаются. Таким образом, вы либо упускаете ссылку, либо используете автомобили, когда этого делать не следует. В какой строке возникает исключение? msdn.microsoft.com/en-us/library /w7xf6dxs(v=vs.110).aspx   -  person Pharap    schedule 17.11.2013
comment
Я думаю, вы правы, но возможно ли программно добавить пространство имен/ссылку в приложение?   -  person cyrus-d    schedule 17.11.2013
comment
Вам не нужно «использовать» пространство имен, если вы динамически загружаете типы. Вы управляете типом, используя его объект типа для создания ссылки, а затем приводя его к чему-то, что он реализует/наследует. Чтобы упростить написание плагинов, лучше всего предоставить библиотеку/API с классами и интерфейсами для любых плагинов, которые можно использовать для связи с вашей программой.   -  person Pharap    schedule 17.11.2013
comment
ну, это правильно, с интерфейсами я могу установить связь со своим приложением, но я ищу способ загрузки внешних сборок без использования интерфейсов, я думаю, что это невозможно. Большое спасибо за вашу помощь, я очень ценю это.   -  person cyrus-d    schedule 17.11.2013
comment
Вы можете просто опросить типы загруженной сборки и их методы, но гораздо проще, если типы в сборке реализуют интерфейсы или классы, о которых знает основная программа, поскольку затем она может работать с ними вручную вместо того, чтобы все время вызывать методы с использованием отражения. . Если по какой-то причине вы не можете предоставить полный API, вы можете продолжать делать то, что делаете, и просто использовать отражение с такими методами, как type.GetMethod(methodName).Invoke(parameters).   -  person Pharap    schedule 17.11.2013


Ответы (1)


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

Чтобы правильно управлять плагинами, вы должны предоставить общий API в виде библиотеки. API должен предоставлять интерфейсы и классы, достаточно абстрактные, чтобы их мог использовать любой подключаемый модуль для правильной регистрации. Они должны раскрывать достаточно для выполнения действий, которые вы ожидаете или разрешаете (например, изменение интерфейса, добавление способа обработки определенных типов контента), но не должны раскрывать большое количество внутренней работы или защищенной информации.

Существует два способа определения плагина: они могут быть .exe или .dll.

Если вы определите их как .exe, вы можете заставить их принимать классы, определенные в API плагина, которые они затем используют для регистрации. Пример:

Основная программа:

void LoadPlugin(string fullPath)
{
Assembly assembly = Assembly.FromFile(fullPath);
//class that provides methods for registering plugins
IPluginRegistrationService registration = new PluginRegistrationService();
assembly.EntryPoint.Invoke(null,new object[] { registration });
}

Плагин:

static void main(IPluginRegistrationService registration)
{
//do registration work
//for example:
//registration.RegisterUIPlugin(new UIPluginInfo("plugin name"));
}

Если вы определяете их как .dll, программа сама должна искать и создавать экземпляры классов, которые реализуют интерфейс/класс, определяющий запись плагина. Пример:

ОсновнаяПрограмма:

void LoadPlugin(string fullPath)
{
Assembly assembly = Assembly.LoadFile(file);
foreach (Module module in assembly.GetModules())
{
foreach (Type type in module.GetTypes())
{
if (type.IsSubclassOf(typeof(IPlugin)))
{ 
//poll constructors and instantiate type
//do work to load plugin based on values
}
}
}
}

Плагин:

public class CarPlugin : IPlugin
{
//implement IPlugin members to expose
//information such as name 
}
person Pharap    schedule 17.11.2013
comment
Большое спасибо за ваше решение, оно очень полезно. я ценю это. - person cyrus-d; 19.11.2013
comment
Пожалуйста. Ради интереса, именно так некоторые игры получают DLC. MVC, похоже, сильно зависит от отражения. - person Pharap; 21.11.2013