Можно ли назначить интерфейс для объекта во время выполнения? - PullRequest
4 голосов
/ 03 августа 2010

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

Взять, к примеру, упрощенную часть кода из моего предыдущего вопроса :

public class OutboxManager
{
    private IVendorMessenger _VendorMessenger;

    //This is the default constructor, forcing the consumer to provide
    //the implementation of IVendorMessenger.
    public OutboxManager(IVendorMessenger messenger)
    {
         _VendorMessenger = messenger;
    }

    public void DistributeOutboxMessages()
    {
        VendorMessenger.SendMessageToVendor()
                      _OutboxMgrDataProvider.MarkMessageAsProcessed(om)
    }

}

В настоящее время, если кто-то хочет использовать этот класс, он должен кодировать класс, который реализует IVendorMessenger, и предоставлять его во время инициализации в качестве параметра:

 var MyOutboxManger = new OutboxManager(new MyVendorMessenger())

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

Возможен ли этот тип функциональности в .NET 4?

Ответы [ 5 ]

4 голосов
/ 03 августа 2010

Проверьте Managed Extensibility Framework (MEF) Он может автоматически составлять зависимости вашего приложения так же, как вы описываете. Поставляется с .NET 4.0.

2 голосов
/ 04 августа 2010

Это довольно распространенный вариант использования для отражения..NET API предоставляет вам необходимые компоненты:

  1. Найти все .dll в каталоге: Directory.GetFiles()
  2. Загрузить эти сборки ввремя выполнения: Assembly.LoadFile()
  3. Перебирайте типы в каждой сборке: Assembly.GetTypes()
  4. Для каждого типа посмотрите, реализует ли он ваш интерфейс: Type.IsAssignableFrom()
  5. Если это так, получить и вызвать его конструктор, чтобы создать его: Type.GetConstructor()

После этого,у вас есть Object, который вы можете разыграть на IVendorMessenger и передать его.

1 голос
/ 03 августа 2010

Вы должны быть в состоянии сделать это очень хорошо (классно) в .Net 2.0 / 3.0 с Generics .

Вы также можете использовать Reflection для загрузки DLL во время выполнения .

1 голос
/ 03 августа 2010

РЕДАКТИРОВАТЬ: Я только что понял, что я неправильно понял вопрос. Вопрос не , на самом деле, кажется, о назначении интерфейса объекту во время выполнения, а скорее о поздних именах типов привязки.

Я оставлю ответ на вики Сообщества на тот случай, если кто-то еще ошибается.


Это обычно называется Внедрение интерфейса и было в списке пожеланий для CLI и JVM, пока они существуют.

Особенно люди, которые пишут реализации для языков программирования, которые изначально не были разработаны для CLI или JVM, такие как JRuby, XRuby, Ruby.NET, IronRuby, IronPython, Jython, Rhino, IronJS и т. Д., Имеют эту функцию высоко их список пожеланий, потому что это означает, что им больше не нужно поддерживать иерархию параллельных типов и маршалировать объекты назад и вперед между ними.

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

1 голос
/ 03 августа 2010

Вы думаете об использовании MEF?Это позволяет создавать приложения из множества модулей.

Вы можете увидеть это здесь

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...