2014-04-09 2 views
0

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

public class Class1 
{ 
    public int Number { get; set; } 
    public string GetWorld() 
    { 
     return "Hello world!"; 
    } 
} 

В моей программе код динамической нагрузке эта библиотеки и функции TestLibraryMethod возвращает экземпляр класса из библиотеки. Так как это написано правильно?

class Program 
{ 
    static void Main(string[] args) 
    { 
     try 
     { 
      var DLL = Assembly.LoadFile(@"C:\TestLibrary.dll"); 
      var reportType = DLL.GetTypes().ToList().Where(t => t.Name == "Class1").Single(); 
      var instance = Activator.CreateInstance(reportType); 
      Class1 test=(call TestLibraryMethod()?) 
      Console.WriteLine(test.Number); 
      Console.WriteLine(test.GetWorld());        
     } 
     catch (Exception e) 
     { 
      Console.WriteLine(e); 
     } 
    } 

    public static Class1 TestLibraryMethod() 
    { 
     Class1 test = new Class1(); 
     test.Number = 5; 
     return test; 
    } 
} 
+2

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

+0

Я понимаю, что это невозможно. В этой ситуации я задаю в этой теме, как было бы лучше? – user3231442

+0

Мне интересно, почему вы это делаете. Основная причина, по которой я могу думать о динамической загрузке таких сборок, - это такие вещи, как плагины, и в этом случае я ожидаю, что у вас будет интерфейс, который они должны реализовать, чтобы затем использовать его для обозначения этого типа. Возможно, вы должны объяснить немного больше о том, что вы пытаетесь достичь здесь? – Chris

ответ

0

Поскольку тип не известен на этапе компиляции вашего процесса, вам необходимо использовать отражение для доступа к нему. Вы можете найти introduction to that topic on MSDN.

Например, принимая ваш пример, чтобы прочитать свойство и вызвать метод вы бы написать это:

PropertyInfo NumberProp = reportType.GetProperty("Number"); 
Console.WriteLine(NumberProp.GetValue(instance)); 

MethodInfo GetWorldMethod = reportType.GetMethod("GetWorld"); 
Console.WriteLine(GetWorldMethod.Invoke(instance, null)); 

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

0

Что имел в виду @David, вы не можете это делать обычно. Однако, если вы все еще хотите такую ​​функциональность, вам нужно подумать о интерфейсах (или контрактах), чтобы это сделать.

Say в сборке А, у вас есть интерфейс, определенный:

public interface IRunnable 
{ 
    void Run(); 
} 

В сборочном B вы имеете конкретную реализацию. Поэтому эта сборка ссылается на A. Поэтому класс в сборке реализует IRunnable.

В своем интерфейсе, то есть в целевом узле (это может быть настольное приложение или веб-приложение или любое приложение), вы добавляете ссылку на сборку A. Сборка B динамически загружается. И этот конкретный тип создается, как вы делали выше, и экземпляр присваивает переменной IRunnable.

Так что в вашем случае код инстансы будет:

var instance = (IRunnable) Activator.CreateInstance(reportType); 
instance.Run(); 

Это рекомендуемый способ сделать это.

Смежные вопросы