Как сохранить динамически загружаемые сборки с нарушением кода во время компиляции?

Я связываю один из внешних ресурсов во время выполнения в своем коде, используя что-то вроде ниже:

System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom("MyNice.dll");
            Type type = assembly.GetType("MyType");
            Tool = Activator.CreateInstance(type) as Tool;

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

Теперь это плохая ситуация, потому что я хотел удалить Dll из своих ссылок и динамически загружать ее во время выполнения, но в то же время есть фрагменты моего кода, которые ссылаются на сборку Tool и зависят от нее. Как я могу сделать его независимым? Должен ли я использовать отражение во всем моем коде или есть какая-то простая альтернатива?

Например:

if (Tool.ApplicationIsOpen)
                    return StatusResult.Success;

находится в том же классе, который предполагает, что класс Tool уже существует и сломается, если я удалю его из своей папки ссылок.

Любые предложения?


person Lost    schedule 21.08.2013    source источник


Ответы (1)


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

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

Общий проект

public interface ITool
{
    void Something();
}

Отдельный проект

public class Tool : ITool
{
    public void Something()
    {
        // do something
    }
}

Потребительский проект

System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFrom("MyNice.dll");
Type type = assembly.GetTypes().FirstOrDefault(t => t.IsAssignableFrom(typeof(ITool)));
ITool tool = Activator.CreateInstance(type) as ITool;

Теперь вы можете удалить ссылку на проект, содержащий Tool, но вам по-прежнему нужна ссылка на общий проект, содержащий ITool. Если вам действительно не нужны какие-либо ссылки, изучите маршрут отражения, но имейте в виду, что он, вероятно, будет грязным.

Эта стратегия является основой для многих систем плагинов. Я бы порекомендовал вам проверить некоторые библиотеки Dependency Injection (DI для краткости), которые могут сделать большую часть этой тяжелой работы за вас.

Вот список библиотек внедрения зависимостей: http://www.hanselman.com/blog/ListOfNETDependencyInjectionContainersIOC.aspx Лично я в последнее время использую Ninject.

Некоторые соответствующие ссылки:

person Hack    schedule 22.08.2013
comment
Я пытаюсь сделать что-то похожее на то, что вы только что предложили. Но вот проблема. Экземпляр класса, который я пытаюсь создать, имеет много членов. Некоторые из них имеют тип Native из этой сборки. ТАК, если я помещу между ними inter ITool, как он узнает типы членов данных, которые являются исключительно родными для исходной сборки? - person Lost; 22.08.2013
comment
Еще одна вещь заключается в том, что в вашем примере Отдельный проект - это наш собственный проект, но в моей ситуации это проект плагина, и я не контролирую его код.... - person Lost; 22.08.2013
comment
Каждый собственный тип из сборки, которую Tool предоставляет в качестве членов, также должен иметь интерфейс в общем проекте. Я мог бы сделать пример проекта, если хотите. У вас есть доступ для изменения кода инструмента? - person Hack; 23.08.2013
comment
Опять же, где будет находиться общедоступный класс Tool : ITool { public void Something() { // do something } }? - person Lost; 23.08.2013
comment
Вы предполагаете, что класс Tool является их классом, который я могу изменить, чтобы унаследовать от моего интерфейса?› - person Lost; 23.08.2013
comment
Да, я предполагал, что вы можете изменить код инструмента, если вы не можете, то этот метод не будет работать. Почему вы хотите удалить ссылку на этот проект? - person Hack; 23.08.2013
comment
Какое-то деловое решение... Ничего такого, что я могу контролировать... Но я думаю, что кто-то, должно быть, сталкивался с чем-то подобным. Я также пытался использовать ключевое слово dynamic в объявлении переменной, и оно не выдавало никаких ошибок во время компиляции, но с ошибкой привязки во время выполнения... вот сообщение, которое я недавно опубликовал: stackoverflow.com/questions/18392186/ - person Lost; 23.08.2013