Выбор инфраструктуры плагинов - PullRequest
3 голосов
/ 06 сентября 2010

[Я читал предыдущие сообщения о MEF против MAF против DI и т. Д., Они не помогают мне с моей конкретной проблемой]

Я ищу написать приложение .Net (возможно, консоль или сервис Windoes), которое будет расширяемым. Это приложение на ночь / расписание, которое извлекает данные из базы данных, что-то с ними делает, а затем выводит (или передает в другую систему).

Я не уверен, что лучший способ определить этот процесс для плагинов. Компоненты:

  • Задача - определение фактической задачи, содержащей определения плагинов и флаг, основанный на событиях, когда запускать (EOD, EOW, EOM)
  • Источник - источник данных (задача может иметь от одного до многих источников), это может быть запрос SQL / хранимый процесс, веб-служба или, возможно, файл. Я вижу это вывод данных.
  • PostProcess - обработка, необходимая для выполнения на выходе источника (у задачи не будет ни одного из множества шагов после обработки), это может быть агрегатор или какая-то особая обработка). Это получит набор данных (содержащий таблицу данных из предыдущего шага). Они должны работать в определенном порядке из-за зависимостей.
  • Target - конечный результат (также один ко многим), это может быть инструкция SQL / сохраненный процесс, загрузка данных, электронная почта, файл вывода или веб-служба

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

Я смотрел на MEF, MAF, DI или просто определял свою собственную структуру. На этом этапе я склоняюсь к развитию своей собственной, просто интересно, пропустил ли я что-нибудь?

Я на самом деле хотел бы использовать MEF, однако, поскольку мне нужно определить мою задачу (т. Е. Ссылки на задачи, на какие источники ссылаются, на какие ссылки PostProcess, на какую цель), а также на отсутствие доступа к конфигурации. Я видел, как примитивы MEF и каталоги типов помогают мне в этом, но, похоже, не помогают в цепочке плагинов. MEF - правильный выбор?

Ответы [ 3 ]

3 голосов
/ 06 сентября 2010

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

[Export(typeof(ITask))]
[ExportMetadata("Requires", "source1")]
public class Task1: ITask
{
    ...
}

Передача конфигурации с помощью MEF очень проста. Хост-приложение может экспортировать себя, и все плагины импортируют его и имеют доступ к своему интерфейсу. Смотрите мой пример ниже:

Интерфейс:

public interface IMainApp
{
    ConfigClass Config { get; set; } 
}

Хост-приложение:

[Export(typeof(IMainApp))]
public class Host : IMainApp
{
    public Host()
    { /* Compose parts here..? */ }

    public ConfigClass Config { get; set; }  

    [Import(typeof(IModule))]
    public List<IModule> LoadedModules { get; set; }
}

Плагин в сборе:

[Export(typeof(IModule))]
public class Module : IModule
{        
    public Module() { }

    [Import(typeof(IMainApp))]
    public IMainApp Host { get; set; } 

    public void DoSomething()
    {
        Host.Config... // use config here
    }
}
1 голос
/ 22 октября 2010

Возможно, вы захотите взглянуть на Mono.Addins .Вы можете определить точку расширения для каждой из частей (чтобы плагины могли определять новые типы источников или целей), а затем вы могли бы создать точку расширения для определения задач.В более поздней точке расширения вы будете определять каждую задачу и то, как они связаны с источниками и целями.

Например, источник может быть определен в плагине следующим образом:

[Extension (Id="MySource")]
class MySource: ISource
{
  ...
}

Иточка расширения для определения задач может быть такой:

<Extension path="/MyApp/Tasks">
    <Task id="someTask">
        <Source sourceId="MySource" />
        <Target targetId="MyTarget" />
    </Task>
    ...
</Extension>
1 голос
/ 06 сентября 2010

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

...