А>Здравствуйте, Ziaw, Вы писали:
public interface IAction<TSetting>
{
TSetting Settings { get; set; }
}
Z>>А теперь расскажите зачем нужен этот интерфейс?
Вопрос был как можно красиво описать setting в интерфейсе. Всё остальное для краткости я опустил =)
Z>>Как наиболее универсальный вариант:
public interface IAction
{
ISettings Settings { get; }
}
public interface ISettings
{
IEnumerable<string> PropertyNames {get;}
object this[string propName] {get;set;}
}
Ваша идея позволить любому экшену работать с любыми настройками это серьёзный overhead, который кроме громоздкого, трудночитаемого кода и кучи проблем ничего не принесёт.
Да и реализация невнятна. Как по вашему будут выглядеть PlayAudioSetting или MeasureBreathSettings ?
Конкретному Action'у нужен конкретный тип Settings. PlayAudioAction знает в его settings лежит путь к файлу, а не количество вдохов в секунду. Поэтому он смело может юзать PlayAudioSetting
и не париться =)
А>Эти настройки будет отображаться в GUI, чтобы пользователь мог сконфигурировать каждый процесс.
А>Например, для
А>PlayAudio — будет строка для ввода пути к файлу
А>для
А>MeasureBreath — будет возможность у пользователя поставить "галочку" либо на запись в теч. Х сек (Х — тоже user конфигурирует), либо на запись Y вдохов (Y — тоже устанавливает пользователь в форме)
Насколько я понял система позволяет созадавать Actions с определёнными настройками, сохранять его, а затем в нужный момент запускать. Абстрагироваться от действия система должна на момент сохранения/запуска. При создании думаю известен конкретный тип действия.
На данный момент IAction представляет собой просто набор параметров действия. Чтобы это всё заработало, нужно добавить в IAction метод Invoke(), или actionPerformed() как писал Other Sam.
Если действия могут запускатся в разном окружении, то его(окружение) нужно передавать в Invoke.
public interface IAction<TSetting>
//where TSetting : ISettings если у settings найдётся что - нибудь общее. Из примера этого не видно.
{
Name // имя
Description // описание
TimeStart // когда начинать процесс
...
TSetting Settings;
IActionResult Invoke(IActionContext context);
}
Если одно и то же действие может совершаться по разному — например PlayAudio используя различные проигрыватели, можно использовать паттерн strategy.
Реализация зависит, от того известна стратегия на момент создания действия или в момент выполнения.
Теперь с гуя можно создавать объекты Action(напрямую или через Factory) и сохранять если надо. Вызывающий поток берёт экшн и через интерфейс запускает его, дёргая Invoke.
Т.е. по сути нужно реализовать паттерн Command, если я правильно понял. =)