Архитектура Плагина C# с интерфейсами совместно использует между плагинами

Если вы обрабатываете большие списки, этот метод не очень хорошая идея. Но это делает работу.

array = ['a', 'b', 'c']
print(array[0]+array[1]+array[2])
16
задан Erik Beijer 6 May 2009 в 13:57
поделиться

5 ответов

Я просто попытался воссоздать ваше решение как можно лучше, и у меня нет таких проблем. (Внимание, за этим следует множество примеров кода).

Первый проект - это приложение, оно содержит один класс:

public class PluginLoader : ILoader
{
    private List<Type> _providers = new List<Type>();

    public PluginLoader()
    {
        LoadProviders();
        LoadConsumers();
    }

    public IProvider RequestProvider(Type providerType)
    {
        foreach(Type t in _providers)
        {
            if (t.GetInterfaces().Contains(providerType))
            {
                return (IProvider)Activator.CreateInstance(t);
            }
        }
        return null;
    }

    private void LoadProviders()
    {
        DirectoryInfo di = new DirectoryInfo(PluginSearchPath);
        FileInfo[] assemblies = di.GetFiles("*.dll");
        foreach (FileInfo assembly in assemblies)
        {
            Assembly a = Assembly.LoadFrom(assembly.FullName);
            foreach (Type type in a.GetTypes())
            {
                if (type.GetInterfaces().Contains(typeof(IProvider)))
                {
                    _providers.Add(type);
                }
            }
        }

    }

    private void LoadConsumers()
    {
        DirectoryInfo di = new DirectoryInfo(PluginSearchPath);
        FileInfo[] assemblies = di.GetFiles("*.dll");
        foreach (FileInfo assembly in assemblies)
        {
            Assembly a = Assembly.LoadFrom(assembly.FullName);
            foreach (Type type in a.GetTypes())
            {
                if (type.GetInterfaces().Contains(typeof(IConsumer)))
                {
                    IConsumer consumer = (IConsumer)Activator.CreateInstance(type);
                    consumer.Initialize(this);
                }
            }
        }
    }

Очевидно, что это можно привести в порядок.

Следующим проектом является разделяемая библиотека, которая содержит следующие три интерфейса:

public interface ILoader
{
    IProvider RequestProvider(Type providerType);
}

public interface IConsumer
{
    void Initialize(ILoader loader);
}

public interface IProvider
{
}

Наконец, существует проект плагина с этими классами:

public interface ITest : IProvider
{        
}

public class TestConsumer : IConsumer
{
    public void Initialize(ILoader loader)
    {
        ITest tester = (ITest)loader.RequestProvider(typeof (ITest));
    }
}

public class TestProvider : ITest
{        
}

И приложение, и проекты плагина ссылаются на общий проект, и библиотека dll плагина копируется в каталог поиска для приложения - но они не ссылаются друг на друга.

Когда PluginLoader создается, он находит все IProviders, затем создает все IConsumers и вызывает Initialize для них. Внутри инициализации потребитель может запросить поставщиков из загрузчика, и в случае этого кода создается TestProvider и возвращается. Все это работает для меня без какого-либо сложного контроля загрузки сборок.

15
ответ дан 30 November 2019 в 22:10
поделиться

Он все еще находится в разработке, но звучит как идеальный вариант использования для MEF (будет включен в .Net 4) и используется внутри VS2010.

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

Предварительные просмотры уже доступны на http://www.codeplex.com/MEF

Блог Glen Block также может быть полезен.

4
ответ дан 30 November 2019 в 22:10
поделиться

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

Плагины в C # Basic Tutorial:

http://www.codeproject.com/KB/cs/pluginsincsharp.aspx

Последующая статья с библиотекой диспетчера подключаемых модулей с общей поддержкой:

http://www.codeproject.com/KB/cs /ExtensionManagerLibrary.aspx

2
ответ дан 30 November 2019 в 22:10
поделиться

Если у вас есть вопрос, как две несвязанные сборки могут использовать один и тот же интерфейс, ответ «вы не можете». Решение состоит в том, чтобы включить интерфейс во все сборки, возможно, в dll, который компоновщики плагинов могут ссылаться и в вашей загрузочной сборке.

0
ответ дан 30 November 2019 в 22:10
поделиться

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

Вы пытались поместить все свои сборки в подкаталог, где находится exe-файл? Сейчас я не могу вспомнить подробности, но есть список шагов, документированных относительно того, где и в каком порядке загрузчик ищет сборки / типы.

0
ответ дан 30 November 2019 в 22:10
поделиться
Другие вопросы по тегам:

Похожие вопросы: