Использование .NET Activator.CreateInstance без использования DTO

У меня есть класс Form, который содержит несколько пользовательских элементов формы.

У меня есть объект Entity, который предоставляет определенные атрибуты для элемента, они анализируются из файла XML. Все элементы принимают Entity в качестве параметра в своем конструкторе, но после этого требуют других параметров в своем конструкторе.

Для создания элемента я использую оператор switch, как показано ниже. Однако я хочу преобразовать это, чтобы использовать Activator.CreateInstance. Однако с разными параметрами в конструкторе единственный известный мне способ справиться с этим - создать DTO, который содержит все параметры, передать его в конструктор, а затем каждый конструктор запросит любую требуемую информацию. Мне нужна альтернатива, поскольку я понимаю, что DTO не одобряется в современных имплементациях.

        switch (entity.GetPropertyValue("Class"))
        {
            case "FormCheckBox":
                newElement = new FormCheckBox(entity, BaseElementHeight);
                break;
            case "RowSeparator":
                newElement = new RowSeperator(entity, RowHeight, _mainCanvas);
                break;
            case "FormLabel":
                newElement = new FormLabel(entity, BaseElementHeight);
                break;
            case "FormEditBox":
                newElement = new FormEditBox(entity, _mainCanvas);//, BaseElementHeight, 600);
                break;
            case "FormComboBox":
                newElement = new FormComboBox(entity, BaseElementHeight);
                break;
            case "FormTextBox":
                newElement = new FormTextBox(entity, BaseElementHeight, TextFontSize, MaxFontBoxSize);
                break;
            default:
                return null;
        }

Есть у кого мысли и/или идеи по этому поводу?


person WPFNewbie    schedule 22.12.2011    source источник


Ответы (2)


вместо того, чтобы вводить все в ctor объекта, почему бы не использовать шаблон команды или шаблон двойной отправки.

Вместо передачи объекта в качестве аргумента ctor сделайте его свойством или просто передайте необходимые свойства.

new FormCheckBox
{
   Height = BaseElementHeight,
   Number = entity.Number, 
   Text = entity.Text 
   ...
};

Это полностью удерживает сущность за пределами пользовательского интерфейса.

person Jason Meckley    schedule 22.12.2011
comment
Не могли бы вы уточнить ваше первое утверждение? Что касается вашего второго утверждения, у моих объектов нет кода пользовательского интерфейса. На самом деле мои объекты действительно знают только о своих данных и отношениях с другими объектами. У меня есть общий метод вызовов классов сущностей GetPropertyValue, аналогичный GetAttribute в XML. Внутри элементов формы, которые являются моим пользовательским интерфейсом, они принимают ссылку на сущность и запрашивают ее, чтобы узнать информацию, необходимую для правильного отображения и поведения. - person WPFNewbie; 22.12.2011
comment
visitor pattern может быть более подходящим, но применяются те же концепции. держите сущность вне пользовательского интерфейса. - person Jason Meckley; 22.12.2011
comment
Спасибо. В моем случае некоторым элементам формы может потребоваться доступ к 20 свойствам сущности. Сущность может содержать такие данные, как тип проверки, маска ввода, обязательность, максимальное количество символов, минимальное количество символов и только для чтения, и это лишь некоторые из них. Я предполагаю, что DTO может быть уместным здесь. Существуют также параметры, которые необходимо передать, которые не являются свойствами сущности, например высота, которая определяется формой потребления. - person WPFNewbie; 22.12.2011
comment
похоже, что на самом объекте слишком много ответственности. я бы нашел способ извлечь и инкапсулировать требования проверки в свой собственный компонент или набор компонентов. - person Jason Meckley; 22.12.2011
comment
Кроме того, в подходе, который вы описываете, как это может позволить мне использовать метод Activator.CreateInstance? Другая часть моей проблемы заключается в том, что мои элементы имеют разные ctors. Должен ли я придумать один главный список параметров, который использует каждый объект, некоторые параметры которого он просто проигнорирует, или я должен просто продолжать использовать оператор switch. Мне все еще нужно добавить еще около 6 типов элементов формы, поэтому переключение становится длинным, и я хочу избежать его обслуживания. - person WPFNewbie; 22.12.2011
comment
Я также считаю, что именно здесь требования к пользовательскому интерфейсу просачиваются в домен. домен не должен заботиться о том, как данные проверяются, только о том, что данные, которые он получает, действительны. и это можно контролировать с помощью дизайна домена, а не списка валидаторов. - person Jason Meckley; 22.12.2011
comment
Я очень ценю ваше понимание. Как мы могли бы перевести это в автономный режим? - person WPFNewbie; 22.12.2011
comment
давайте продолжим это обсуждение в чате - person Jason Meckley; 22.12.2011

Нужно ли передавать параметр конструктору? Если нет, я бы предложил создать объект по соглашению об именах (как показывает ваш случай, это возможно), а затем, всегда используя соглашение, через отражение установить каждое свойство. Поскольку значение, которое у вас есть в XML, всегда является строкой, вы, вероятно, захотите передать его в Convert.ChangeType() целевому типу свойства, чтобы получить изящное рабочее назначение.

person Felice Pollano    schedule 22.12.2011
comment
мы в чате, если вы хотите присоединиться к нам. - person Jason Meckley; 22.12.2011