2013-12-24 4 views
1

У меня есть DLL, которую я хочу загрузить во время выполнения. Я использую Assembly.Load (byte []) и .CreateInstance() загруженной сборки.Assembly.CreateInstance(): как реализовать реализацию интерфейса

В этой сборке, у меня есть интерфейс IAnimal и корова, которая реализует этот интерфейс:

namespace DynamicLoading 
{  
    public class Cow : IAnimal 
    { 
     public string GetName() 
     { 
      return "This is cow"; 
     } 
    } 

    public interface IAnimal 
    { 
     string GetName(); 
    } 
} 

я использую консольное приложение для testload это:

namespace DynamicLoading 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      byte[] assemblyStream = System.IO.File.ReadAllBytes(@"C:\Cow\Cow.dll"); 

      var cow = Assembly.Load(assemblyStream); 

      //Returns null: it is not able to cast from Cow to IAnimal 
      var newCow = cow.CreateInstance("DynamicLoading.Cow", false) as IAnimal; 

      Console.WriteLine(newCow.GetName());     

      Console.ReadLine(); 
     } 
    } 

    public interface IAnimal 
    { 
     string GetName(); 
    } 
} 

я могу создать экземпляр Cow отлично, но я не могу заставить интерфейс IAnimal (который я создал как в своем тестовом проекте, так и в проекте dll). Корова из dll не хочет, чтобы ее отливали от IAnimal из тестового класса.

Как мне вызвать методы на корову, такие как GetName()?

Приветствия ребята!

+0

Где находится 'IAnimal'? –

+0

, так что вы получаете ошибку на этой строке «var newCow = cow.CreateInstance (« DynamicLoading.Cow », false) как IAnimal;» ? –

+0

@RogerLipscombe Как вы можете видеть, он определяется как в тестовом приложении, так и в библиотеке классов. – Recipe

ответ

3

Интерфейс пользователя в Cow.dll НЕ совпадает с вашим интерфейсом в другой сборке. Независимо от того, существует ли тот же интерфейс с тем же именем в одном и том же пространстве имен.

Что вам нужно сделать, это определить интерфейс в «общем» место, которое видно на обоих Cow.dll и вашу программу сборке:

- Animals.Common.Dll 
    - interface IAnimal 

- Animals.Cow.Dll 
    - References 
     - Animals.Common.Dll 
    - class Cow: IAnimal 

- Animals.Main.exe (Console Application) 
    - References 
     - Animals.Common.Dll 
    - class Program 
1

Не определяйте интерфейс в нескольких местах, версия, реализованная в вашей библиотеке DynamicLoading, не совпадает с версией в вашей библиотеке классов.

Создайте одну его версию в 3-й сборке и ссылке, как с консоли, так и с помощью узлов DynamicLoading.

E.g.

Ассамблея DynamicLoading.Core IAnimal

Ассамблея DynamicLoading.Cow - Справочник DynamicLoading.Core

Consoe Применение - Справочник DynamicLoading.Core

2

У вас есть два различных интерфейса, даже если они имеют то же самое FullName, они отличаются своим AssemblyQualifiedName, поскольку они принадлежат к двум различным сборкам.

Используйте единое определение интерфейса IAnimal в некоторой общей сборке, на которую ссылаются оба проекта.

Если вы хотите регулярно делать подобные вещи (динамическая загрузка типов), взгляните на MAF, который был разработан для создания аддинов.

1

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

Существует несколько способов решить эту проблему в зависимости от структуры вашего приложения и того, что вы в конечном итоге пытаетесь выполнить.

Один подход будет иметь сборка коровы имеют ссылку на ваш основной узел и есть корова реализовать интерфейс IAnimal оттуда:

namespace Plugin 
{ 
    public class Cow : MainAssembly.IAnimal { } 
} 

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

internal class AnimalProxy : IAnimal 
{ 
    private object _target; 
    public AnimalProxy(object target) 
    { 
     _target = target; 
    } 

    public string GetName() 
    { 
     //probably want to add error handling 
     return _target.GetType().GetMethod("GetName").Invoke(_target) as string; 
    } 
} 
Смежные вопросы