Я столкнулся с небольшой проблемой, и я ищу лучшую концепцию / теорию решения.
У меня есть система, которая должна использовать объекты.Каждый объект, который использует система, имеет известный интерфейс, вероятно, реализованный как абстрактный класс.Интерфейсы известны во время сборки и не изменятся.Точная реализация будет варьироваться, и я заранее не знаю, какой модуль будет ее предоставлять.Единственная гарантия, что они предоставят интерфейс.Имя класса и модуль (DLL) взяты из файла конфигурации или могут быть изменены программно.
Теперь у меня есть все, что настроено на данный момент с использованием относительно простой системы, настроить что-то вроде этого (переписано псевдо-код, просто чтобы показать основы):
struct ClassID
{
Module * module;
int number;
};
class Module
{
HMODULE module;
function<void * (int)> * createfunc;
static Module * Load(String filename);
IObject * CreateClass(int number)
{
return createfunc(number);
}
};
class ModuleManager
{
bool LoadModule(String filename);
IObject * CreateClass(String classname)
{
ClassID class = AvailableClasses.find(classname);
return class.module->CreateObject(class.number);
}
vector<Module*> LoadedModules;
map<String, ClassID> AvailableClasses;
};
Модули имеют несколько экспортируемых функций для определения количества классов, которые они предоставляют, и имен / идентификаторов тех, которые затем сохраняются.Все классы являются производными от IObject
, который имеет виртуальный деструктор, хранит исходный модуль и имеет несколько методов для получения идентификатора класса, какой интерфейс он реализует и тому подобное.
Единственная проблема с этим - каждый модульдолжен быть где-то загружен вручную (указан в конфигурационном файле, на данный момент).Я хотел бы избежать этого в явном виде (за исключением ModuleManager
, внутри которого я не особо обеспокоен тем, как это реализовано).
Я хотел бы иметь подобную систему без необходимости обрабатывать загрузкумодули просто создают объект, и (после того, как он все настроен) он волшебным образом появляется.
Я полагаю, что это в некоторой степени похоже на то, что COM должен делать.Я кратко посмотрел на систему COM, но, похоже, это было слишком сложно.Мне нужны только классы, известные в моей системе, и не нужны все остальные функции, которые она обрабатывает, только реализации интерфейсов, поступающих откуда-то.
Другая моя идея - использовать реестр и хранить ключ со всемиизвестные / зарегистрированные классы и их исходные модули и числа, так что я могу просто посмотреть их, и окажется, что Manager::CreateClass
находит и делает объект волшебным образом.Это кажется жизнеспособным решением, но я не уверен, что оно оптимально или я что-то заново изобретаю.
Итак, после всего этого мой вопрос: как с этим справиться?Существует ли существующая технология, если нет, то как лучше ее настроить?Есть ли какие-то ошибки, на которые мне стоит обратить внимание?