Изучая некоторые шаблоны, я наткнулся на шаблон factory для создания экземпляров (неизвестных) классов. Это меня заинтересовало, поэтому я хочу создать программу, которую можно динамически улучшать. Итак, у меня есть некоторые базовые функции в одной сборке и фактические рабочие функции в разных сборках. Единственный намек, который я получаю от своего приложения, — это имя операции. Теперь я хочу создать нового работника, который зависит от операции. Поскольку я не знаю реальных реализаций рабочих, я выбрал такой шаблон.
Хорошо, подробнее:
У меня есть IWorker
-интерфейс, который реализуют все мои процессы. Синглтон WorkerFactory
позволяет мне создавать новые экземпляры любого работника, реализованного в любой сборке, по тому же пути, что и текущий. Для этого я добавил в свой интерфейс CreateWorker
-метод, который принимает массив строк (которые были переданы как varargs
в консольное приложение).
Прежде чем создать какой-либо экземпляр любого работника, я должен зарегистрировать любой класс на фабрике. К сожалению, в C# невозможно статически вставить такое поведение в любой статический контекст рабочих классов, потому что код в этом контексте выполняется только при доступе к классу каким-либо образом (будь то создание его экземпляра или доступ к любому из его статические члены, см. статические конструкторы). Поэтому я достигаю этого, отражая все типы, найденные во всех сборках, с путем к текущей выполняемой сборке. Теперь я могу проверить, реализует ли текущий тип интерфейс, и если да, то тип можно добавить в карту регистрации фабрики, содержащую имя операции (ключ) и работника (значение) как System.Type
(см. Factory Pattern с использованием отражения). Проблема в том, как мне получить фактическое имя операции, на которую ссылается этот тип.
Я думаю, что есть два варианта для этого:
- Я добавляю статическое свойство к каждому рабочему классу, в котором хранится имя операции. Таким образом, я могу сослаться на операцию, отразив это свойство на полученном типе.
- Добавление нестатического свойства для имени и создание фиктивного экземпляра фактического рабочего класса при регистрации.
В то время как первый вариант имеет недостаток, заключающийся в том, что я не могу гарантировать, что все рабочие процессы действительно реализуют такое статическое свойство (следовательно, невозможно добавить статический член в интерфейс IWorker), второй имеет недостаток, заключающийся в том, что каждый класс должен иметь пустой конструктор для создания фиктивного экземпляра, из которого можно получить имя операции. Тем не менее, этот конструктор будет общедоступным, хотя и не будет содержать никакого кода инициализации.
Сказав, что весь этот вопрос касается лучших или, по крайней мере, лучших практик фабричного шаблона с использованием отражения. Я думаю, что предпочел бы первый вариант, но, возможно, я также пропустил какое-либо лучшее решение для этого подхода.
Следовательно, эта ветка уже довольно длинная. Я бы не хотел публиковать здесь какой-либо код, но дайте мне знать, если вам это нужно.