Идентификация реализаций базового класса в массиве


У меня есть следующая проблема: у меня есть набор движков, которые автоматически (прослушивая события) управляют моей моделью. На следующем рисунке показана общая схема классов: Диаграмма Классов

Теперь у меня есть клиент, который знает EngineFacade, и я хочу установить свойство Active from Engine2 от клиента, но ни клиент, ни EngineFacade не знают, какой из трех двигателей является Engine2.

Есть два способа, но мне не нравится ни один из них:

  1. Проверьте, если один из двигатели имеют тип Engine2 - если есть другой класс, который выполняет ту же задачу, но называется по-другому, я должен изменить его в EngineBuilder и в EngineFacade.
  2. Проверьте с помощью строки идентификатора-я не очень люблю волшебные строки.

Что я знаю на сайте клиента, так это то, что есть или должен быть движок, который обрабатывает сетку. Но больше я ничего не знаю.

Возможно, мне придется выбирать между двумя дьяволами, но, возможно, у одного из вас есть лучшее решение.
1   7  

1 ответ:

Можно использовать атрибут для реализации Engine2, например:

[AttributeUsage(AttributeTargets.Class)]
public class HandlesGridAttribute : Attribute { }

Которые вы затем применяете к своему выводу:

[HandlesGrid]
public Engine2 : EngineBase { ... }

Затем в клиенте проверьте наличие атрибута:

IEnumerable<EngineBase> bases = ...;

// Get all the implementations which handle the grid.
IEnumerable<EngineBase> handlesGrid = bases.
    Where(b => b.GetType().
        GetCustomAttributes(typeof(HandlesGridAttribute), true).Any());

// Set the active property.
foreach (EngineBase b in handlesGrid) b.Active = true;

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

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