2012-04-15 3 views
8

Мое приложение загружает все сборки библиотек, расположенные в его пути выполнения, и выполняет преизвестные методы в отношении содержащихся классов.Загрузите сборку во время выполнения, которая ссылается на вызывающую сборку

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

Мастер сборка:

public abstract class TaskBase 
{ 
    public abstract void DoWork(); 
} 

LoadAssemblyFromFile("Assembly0001.dll"); 
Assembly0001.Task1.DoWork(); 

Дети Сборка:

public sealed class Task1: MasterAssembly.TaskBase 
{ 
    public override void DoWork { /* whatever */ } 
} 
+0

Я делаю это все время без проблем. Единственная проблема, с которой я столкнулся (несколько раз на самом деле), - это управление версиями сборки _master_. Если вы внесете изменения в _master_ без перекомпиляции детей, вы можете столкнуться с некоторыми причудливыми проблемами. –

+0

@ M.Babcock: Спасибо. Из любопытства, какие проблемы? При повторной компиляции я не автоматически увеличиваю версии сборки. Я предполагаю, что СЛЕДУЕТ обойти любые проблемы, с которыми вы столкнулись. Твои мысли? –

+0

Самая распространенная проблема, с которой я столкнулся, заключается в том, что определение метода изменяет разрывную совместимость, хотя в других случаях я испытал, что страшный «_Type_ определяется как в исключении _Master_, так и _Master_» (из памяти, а не в буквальном тексте, но закрывается достаточно, чтобы вы это узнали). –

ответ

6

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

Мастер-сборщик просто загружает дочерние сборки и ничего не знает о них, кроме того, что они реализуют интерфейс. Таким образом, мастер-сборка не требует ссылки на дочерние сборки.

Не знаю, насколько я знаю. Мы успешно используем этот метод для определенных сценариев.

+0

Спасибо. Из контекста, есть ли способ загрузить сборки из памяти без файла сборки, присутствующего на диске? Эти периодические выпуски сборок присутствуют в центральной базе данных, и я бы предпочел сделать их разумно трудными для пользователей. Конечно, я понимаю, что для этого нет надежного способа. –

+0

Да, у нас были мобильные приложения. Бинарная сборка хранилась в базе данных, загружалась и загружалась таким образом. Вы могли бы сделать то же самое. –

+0

Найдено: Assembly.Load (byte []). –

1

В моем опыте нет ничего плохого в этом. Фактически, MEF использует эту технику в виде AssemblyCatalog (где ваши реализации находятся в главной сборке) и DirectoryCatalog (где реализации интерфейса находятся в сборках в определенном каталоге).

Оба могут использоваться вместе в AggregateCatalog без проблем.

0

Единственная «проблема» в том, что вы не можете писать Assembly0001.Task1 в вашем Мастер сборки, но вы можете найти правильную задачу в загруженной сборки и вызова, что один:

var asm = LoadAssemblyFromFile("Assembly0001.dll"); 
var taskType = asm.GetTypes().FirstOrDefault(t => typeof(TaskBase).IsAssignableFrom(t)); 
var task = (TaskBase)Activator.CreateInstance(taskType); 
task.DoWork(); 

Вы будете по-прежнему необходимо добавить дополнительные проверки безопасности:

+0

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

+0

Ну в основном только нулевые проверки, если вы действительно хотите создать песочницу для выполнения своих задач, это может стать немного сложнее. – XIU

0

Вы не отправили код вашего метода LoadAssemblyFromFile ("..."), но если он использует Assembly.LoadFrom() или Assembly.LoadFile() для загрузки сборок, вы может получить InvalidCastException, MissingMethodException или другие исключения, особенно если ваше приложение и загруженная сборка обе ссылки идентичны другим сборкам. LoadFrom() и LoadFile() загружают сборки в разных контекстах привязки, чем ваше приложение. См. this для подробного объяснения.